aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb2
-rw-r--r--actionmailbox/app/jobs/action_mailbox/incineration_job.rb6
-rw-r--r--actionmailbox/app/models/action_mailbox/inbound_email.rb14
-rw-r--r--actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb6
-rw-r--r--actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb6
-rw-r--r--actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb12
-rw-r--r--actionmailbox/app/models/action_mailbox/inbound_email/routable.rb10
-rw-r--r--actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb4
-rw-r--r--actionmailbox/lib/action_mailbox/base.rb24
-rw-r--r--actionmailbox/lib/action_mailbox/router/route.rb2
-rw-r--r--actionmailbox/lib/action_mailbox/routing.rb2
-rw-r--r--actionmailbox/lib/action_mailbox/test_helper.rb12
-rw-r--r--actionpack/CHANGELOG.md4
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb4
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb1
-rw-r--r--actionpack/test/controller/base_test.rb2
-rw-r--r--actionpack/test/controller/url_for_test.rb8
-rw-r--r--guides/source/engines.md21
18 files changed, 74 insertions, 66 deletions
diff --git a/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb b/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb
index ebe83a9ec0..bf0fd562fe 100644
--- a/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb
+++ b/actionmailbox/app/controllers/action_mailbox/ingresses/mailgun/inbound_emails_controller.rb
@@ -38,7 +38,7 @@ module ActionMailbox
# config.action_mailbox.ingress = :mailgun
#
# 3. {Configure Mailgun}[https://documentation.mailgun.com/en/latest/user_manual.html#receiving-forwarding-and-storing-messages]
- # to forward inbound emails to `/rails/action_mailbox/mailgun/inbound_emails/mime`.
+ # to forward inbound emails to +/rails/action_mailbox/mailgun/inbound_emails/mime+.
#
# If your application lived at <tt>https://example.com</tt>, you would specify the fully-qualified URL
# <tt>https://example.com/rails/action_mailbox/mailgun/inbound_emails/mime</tt>.
diff --git a/actionmailbox/app/jobs/action_mailbox/incineration_job.rb b/actionmailbox/app/jobs/action_mailbox/incineration_job.rb
index 224c9329a5..1579a3c7c8 100644
--- a/actionmailbox/app/jobs/action_mailbox/incineration_job.rb
+++ b/actionmailbox/app/jobs/action_mailbox/incineration_job.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module ActionMailbox
- # 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.
+ # 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 `InboundEmail`s
+ # Since this incineration is set for the future, it'll automatically ignore any <tt>InboundEmail</tt>s
# that have already been deleted and discard itself if so.
class IncinerationJob < ActiveJob::Base
queue_as { ActionMailbox.queues[:incineration] }
diff --git a/actionmailbox/app/models/action_mailbox/inbound_email.rb b/actionmailbox/app/models/action_mailbox/inbound_email.rb
index 3a8dfd163c..023de19ccc 100644
--- a/actionmailbox/app/models/action_mailbox/inbound_email.rb
+++ b/actionmailbox/app/models/action_mailbox/inbound_email.rb
@@ -3,22 +3,22 @@
require "mail"
module ActionMailbox
- # The `InboundEmail` is an Active Record that keeps a reference to the raw email stored in Active Storage
+ # 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.
+ # * 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
+ # 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.
+ # 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:
#
diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb
index 825e300648..697331ede4 100644
--- a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb
+++ b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-# 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`.
+# 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+.
module ActionMailbox::InboundEmail::Incineratable
extend ActiveSupport::Concern
diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb
index 685f7fceb6..dabc83fae6 100644
--- a/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb
+++ b/actionmailbox/app/models/action_mailbox/inbound_email/incineratable/incineration.rb
@@ -1,10 +1,10 @@
# frozen_string_literal: true
module ActionMailbox
- # 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
+ # 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).
+ # the +InboundEmail+ was processed after the +incinerate_after+ time).
class InboundEmail::Incineratable::Incineration
def initialize(inbound_email)
@inbound_email = inbound_email
diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb b/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb
index 2ad4525929..57b4a2445d 100644
--- a/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb
+++ b/actionmailbox/app/models/action_mailbox/inbound_email/message_id.rb
@@ -1,11 +1,11 @@
# frozen_string_literal: true
-# 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
+# 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`.
+# using the approach from <tt>Mail::MessageIdField</tt>.
module ActionMailbox::InboundEmail::MessageId
extend ActiveSupport::Concern
@@ -14,9 +14,9 @@ module ActionMailbox::InboundEmail::MessageId
end
class_methods do
- # Create a new `InboundEmail` from the raw `source` of the email, which be uploaded as a 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`.
+ # Create a new +InboundEmail+ from the raw +source+ of the email, which be uploaded as a 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+.
def create_and_extract_message_id!(source, **options)
create! options.merge(message_id: extract_message_id(source)) do |inbound_email|
inbound_email.raw_email.attach io: StringIO.new(source), filename: "message.eml", content_type: "message/rfc822"
diff --git a/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb b/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb
index 58d67eb20c..39565df166 100644
--- a/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb
+++ b/actionmailbox/app/models/action_mailbox/inbound_email/routable.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
-# 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.
+# 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,
+# By default, all newly created +InboundEmail+ records that have the status of +pending+, which is the default,
# will be scheduled for automatic, deferred routing.
module ActionMailbox::InboundEmail::Routable
extend ActiveSupport::Concern
@@ -12,12 +12,12 @@ module ActionMailbox::InboundEmail::Routable
after_create_commit :route_later, if: :pending?
end
- # Enqueue a `RoutingJob` for this `InboundEmail`.
+ # Enqueue a +RoutingJob+ for this +InboundEmail+.
def route_later
ActionMailbox::RoutingJob.perform_later self
end
- # Route this `InboundEmail` using the routing rules declared on the `ApplicationMailbox`.
+ # Route this +InboundEmail+ using the routing rules declared on the +ApplicationMailbox+.
def route
ApplicationMailbox.route self
end
diff --git a/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb b/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb
index 0124b4b98f..8cf621d7e3 100644
--- a/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb
+++ b/actionmailbox/db/migrate/20180917164000_create_action_mailbox_tables.rb
@@ -4,8 +4,8 @@ class CreateActionMailboxTables < ActiveRecord::Migration[6.0]
t.integer :status, default: 0, null: false
t.string :message_id
- t.datetime :created_at, precision: 6
- t.datetime :updated_at, precision: 6
+ t.datetime :created_at, precision: 6, null: false
+ t.datetime :updated_at, precision: 6, null: false
end
end
end
diff --git a/actionmailbox/lib/action_mailbox/base.rb b/actionmailbox/lib/action_mailbox/base.rb
index 4ac594b9f8..ff8587acd1 100644
--- a/actionmailbox/lib/action_mailbox/base.rb
+++ b/actionmailbox/lib/action_mailbox/base.rb
@@ -7,7 +7,7 @@ require "action_mailbox/routing"
module ActionMailbox
# 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
+ # +ApplicationMailbox+ instead, as that's where the app-specific routing is configured. This routing
# is specified in the following ways:
#
# class ApplicationMailbox < ActionMailbox::Base
@@ -27,15 +27,15 @@ module ActionMailbox
# routing :all => :backstop
# end
#
- # Application mailboxes need to overwrite 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 ensure certain preconditions to processing are fulfilled
- # using `before_processing` callbacks.
+ # Application mailboxes need to overwrite 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 ensure 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,
+ # 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
+ # 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
@@ -50,12 +50,12 @@ module ActionMailbox
# 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`.
+ # 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 `Rescuable` approach:
+ # Exceptions can be handled at the class level using the familiar +Rescuable+ approach:
#
# class ForwardsMailbox < ApplicationMailbox
# rescue_from(ApplicationSpecificVerificationError) { bounced! }
diff --git a/actionmailbox/lib/action_mailbox/router/route.rb b/actionmailbox/lib/action_mailbox/router/route.rb
index b681eb7ea8..7e98e83382 100644
--- a/actionmailbox/lib/action_mailbox/router/route.rb
+++ b/actionmailbox/lib/action_mailbox/router/route.rb
@@ -2,7 +2,7 @@
module ActionMailbox
# 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`
+ # mailbox class. See examples for the different route addresses and how to use them in the +ActionMailbox::Base+
# documentation.
class Router::Route
attr_reader :address, :mailbox_name
diff --git a/actionmailbox/lib/action_mailbox/routing.rb b/actionmailbox/lib/action_mailbox/routing.rb
index 1ea96c8a9d..58462a44c6 100644
--- a/actionmailbox/lib/action_mailbox/routing.rb
+++ b/actionmailbox/lib/action_mailbox/routing.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module ActionMailbox
- # See `ActionMailbox::Base` for how to specify routing.
+ # See +ActionMailbox::Base+ for how to specify routing.
module Routing
extend ActiveSupport::Concern
diff --git a/actionmailbox/lib/action_mailbox/test_helper.rb b/actionmailbox/lib/action_mailbox/test_helper.rb
index 02c52fb779..0ec9152844 100644
--- a/actionmailbox/lib/action_mailbox/test_helper.rb
+++ b/actionmailbox/lib/action_mailbox/test_helper.rb
@@ -4,38 +4,38 @@ require "mail"
module ActionMailbox
module TestHelper
- # Create an `InboundEmail` record using an eml fixture in the format of message/rfc822
+ # 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+.
def create_inbound_email_from_fixture(fixture_name, status: :processing)
create_inbound_email_from_source file_fixture(fixture_name).read, status: status
end
- # Create an `InboundEmail` by specifying it using `Mail.new` options. Example:
+ # Create an +InboundEmail+ by specifying it using +Mail.new+ options. Example:
#
# create_inbound_email_from_mail(from: "david@loudthinking.com", subject: "Hello!")
def create_inbound_email_from_mail(status: :processing, **mail_options)
create_inbound_email_from_source Mail.new(mail_options).to_s, status: status
end
- # Create an `InboundEmail` using the raw rfc822 `source` as text.
+ # Create an +InboundEmail+ using the raw rfc822 +source+ as text.
def create_inbound_email_from_source(source, status: :processing)
ActionMailbox::InboundEmail.create_and_extract_message_id! source, status: status
end
- # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_fixture`
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_fixture+
# and immediately route it to processing.
def receive_inbound_email_from_fixture(*args)
create_inbound_email_from_fixture(*args).tap(&:route)
end
- # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_mail`
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_mail+
# and immediately route it to processing.
def receive_inbound_email_from_mail(**kwargs)
create_inbound_email_from_mail(**kwargs).tap(&:route)
end
- # Create an `InboundEmail` from fixture using the same arguments as `create_inbound_email_from_source`
+ # Create an +InboundEmail+ from fixture using the same arguments as +create_inbound_email_from_source+
# and immediately route it to processing.
def receive_inbound_email_from_source(**kwargs)
create_inbound_email_from_source(**kwargs).tap(&:route)
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index 95da4265a4..1457794354 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -85,10 +85,6 @@
*Yoshiyuki Kinjo*
-* Remove undocumented `params` option from `url_for` helper.
-
- *Ilkka Oksanen*
-
* Encode Content-Disposition filenames on `send_data` and `send_file`.
Previously, `send_data 'data', filename: "\u{3042}.txt"` sends
`"filename=\"\u{3042}.txt\""` as Content-Disposition and it can be
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 2966c969f6..972953d4f3 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -820,6 +820,10 @@ module ActionDispatch
path, params = generate(route_name, path_options, recall)
+ if options.key? :params
+ params.merge! options[:params]
+ end
+
options[:path] = path
options[:script_name] = script_name
options[:params] = params
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index 1a31c7dbb8..fcb8ae296b 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -133,6 +133,7 @@ module ActionDispatch
# <tt>ActionDispatch::Http::URL.tld_length</tt>, which in turn defaults to 1.
# * <tt>:port</tt> - Optionally specify the port to connect to.
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
+ # * <tt>:params</tt> - The query parameters to be appended to the path.
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
# * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
#
diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb
index 558e710df9..d8cea10153 100644
--- a/actionpack/test/controller/base_test.rb
+++ b/actionpack/test/controller/base_test.rb
@@ -193,7 +193,7 @@ class UrlOptionsTest < ActionController::TestCase
action: "home",
controller: "pages",
only_path: true,
- token: "secret"
+ params: { "token" => "secret" }
}
assert_equal "/home?token=secret", rs.url_for(options)
diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb
index e381abee36..9222250b9c 100644
--- a/actionpack/test/controller/url_for_test.rb
+++ b/actionpack/test/controller/url_for_test.rb
@@ -354,6 +354,14 @@ module AbstractController
assert_equal({ p2: "Y2" }.to_query, params[1])
end
+ def test_params_option
+ url = W.new.url_for(only_path: true, controller: "c", action: "a", params: { domain: "foo", id: "1" })
+ params = extract_params(url)
+ assert_equal("/c/a?domain=foo&id=1", url)
+ assert_equal({ domain: "foo" }.to_query, params[0])
+ assert_equal({ id: "1" }.to_query, params[1])
+ end
+
def test_hash_parameter
url = W.new.url_for(only_path: true, controller: "c", action: "a", query: { name: "Bob", category: "prof" })
params = extract_params(url)
diff --git a/guides/source/engines.md b/guides/source/engines.md
index c4829299ca..f15383e3f1 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -1091,16 +1091,15 @@ main Rails application.
Engine model and controller classes can be extended by open classing them in the
main Rails application (since model and controller classes are just Ruby classes
that inherit Rails specific functionality). Open classing an Engine class
-redefines it for use in the main application. This is usually implemented by
-using the decorator pattern.
+redefines it for use in the main application.
For simple class modifications, use `Class#class_eval`. For complex class
modifications, consider using `ActiveSupport::Concern`.
-#### A note on Decorators and Loading Code
+#### A note on Overriding and Loading Code
-Because these decorators are not referenced by your Rails application itself,
-Rails' autoloading system will not kick in and load your decorators. This means
+Because these overrides are not referenced by your Rails application itself,
+Rails' autoloading system will not kick in and load your overrides. This means
that you need to require them yourself.
Here is some sample code to do this:
@@ -1112,7 +1111,7 @@ module Blorgh
isolate_namespace Blorgh
config.to_prepare do
- Dir.glob(Rails.root + "app/decorators/**/*_decorator*.rb").each do |c|
+ Dir.glob(Rails.root + "app/overrides/**/*_override*.rb").each do |c|
require_dependency(c)
end
end
@@ -1120,15 +1119,15 @@ module Blorgh
end
```
-This doesn't apply to just Decorators, but anything that you add in an engine
+This doesn't apply to just overrides, but anything that you add in an engine
that isn't referenced by your main application.
-#### Implementing Decorator Pattern Using Class#class_eval
+#### Reopening existing classes using Class#class_eval
**Adding** `Article#time_since_created`:
```ruby
-# MyApp/app/decorators/models/blorgh/article_decorator.rb
+# MyApp/app/overrides/models/blorgh/article_override.rb
Blorgh::Article.class_eval do
def time_since_created
@@ -1149,7 +1148,7 @@ end
**Overriding** `Article#summary`:
```ruby
-# MyApp/app/decorators/models/blorgh/article_decorator.rb
+# MyApp/app/overrides/models/blorgh/article_override.rb
Blorgh::Article.class_eval do
def summary
@@ -1169,7 +1168,7 @@ class Article < ApplicationRecord
end
```
-#### Implementing Decorator Pattern Using ActiveSupport::Concern
+#### Reopening existing classes using ActiveSupport::Concern
Using `Class#class_eval` is great for simple adjustments, but for more complex
class modifications, you might want to consider using [`ActiveSupport::Concern`]