@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'puma' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'puma', version
load Gem.bin_path('puma', 'puma', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'puma' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'puma', version
load Gem.bin_path('puma', 'pumactl', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'rack' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'rack', version
load Gem.bin_path('rack', 'rackup', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'railties' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'railties', version
load Gem.bin_path('railties', 'rails', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'rake' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'rake', version
load Gem.bin_path('rake', 'rake', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'rest-client' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'rest-client', version
load Gem.bin_path('rest-client', 'restclient', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'rspec-core' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'rspec-core', version
load Gem.bin_path('rspec-core', 'rspec', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'rubocop' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'rubocop', version
load Gem.bin_path('rubocop', 'rubocop', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'parser' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'parser', version
load Gem.bin_path('parser', 'ruby-parse', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'parser' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'parser', version
load Gem.bin_path('parser', 'ruby-rewrite', version)
@@ -0,0 +1,25 @@
#!/bin/sh
'exec' "jruby" '-x' "$0" "$@"
#!/Users/ma/.rbenv/versions/jruby-9.0.5.0/bin/jruby
#
# This file was generated by RubyGems.
#
# The application 'ruby_parser' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'ruby_parser', version
load Gem.bin_path('ruby_parser', 'ruby_parse', version)
@@ -0,0 +1,25 @@
#!/bin/sh
'exec' "jruby" '-x' "$0" "$@"
#!/Users/ma/.rbenv/versions/jruby-9.0.5.0/bin/jruby
#
# This file was generated by RubyGems.
#
# The application 'ruby_parser' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'ruby_parser', version
load Gem.bin_path('ruby_parser', 'ruby_parse_extract_error', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'sass' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'sass', version
load Gem.bin_path('sass', 'sass', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'sass' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'sass', version
load Gem.bin_path('sass', 'sass-convert', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'sass' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'sass', version
load Gem.bin_path('sass', 'scss', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'sprockets' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'sprockets', version
load Gem.bin_path('sprockets', 'sprockets', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'thor' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'thor', version
load Gem.bin_path('thor', 'thor', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'tilt' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'tilt', version
load Gem.bin_path('tilt', 'tilt', version)
@@ -0,0 +1,23 @@
#!/usr/bin/env jruby
#
# This file was generated by RubyGems.
#
# The application 'zencoder-fetcher' is installed as part of a gem, and
# this file is here to facilitate running it.
#

require 'rubygems'

version = ">= 0"

if ARGV.first
str = ARGV.first
str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding
if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then
version = $1
ARGV.shift
end
end

gem 'zencoder-fetcher', version
load Gem.bin_path('zencoder-fetcher', 'zencoder_fetcher', version)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,132 @@
## Rails 4.2.7 (July 12, 2016) ##

* Removes `-t` from default Sendmail arguments to match the underlying
`Mail::Sendmail` setting.

*Clayton Liggitt*


## Rails 4.2.6 (March 07, 2016) ##

* No changes.


## Rails 4.2.5.2 (February 26, 2016) ##

* No changes.


## Rails 4.2.5.1 (January 25, 2015) ##

* No changes.


## Rails 4.2.5 (November 12, 2015) ##

* No changes.


## Rails 4.2.4 (August 24, 2015) ##

* No Changes *


## Rails 4.2.3 (June 25, 2015) ##

* `assert_emails` in block form use the given number as expected value.
This makes the error message much easier to understand.

*Yuji Yaginuma*

* Mailer preview now uses `url_for` to fix links to emails for apps running on
a subdirectory.

*Remo Mueller*

* Mailer previews no longer crash when the `mail` method wasn't called
(`NullMail`).

Fixes #19849.

*Yves Senn*

* Make sure labels and values line up in mailer previews.

*Yves Senn*


## Rails 4.2.2 (June 16, 2015) ##

* No Changes *


## Rails 4.2.1 (March 19, 2015) ##

* No Changes *


## Rails 4.2.0 (December 20, 2014) ##

* `MailerGenerator` now generates layouts by default. The HTML mailer layout
now includes `<html>` and `<body>` tags which improve the spam rating in
some spam detection engines. Mailers now inherit from `ApplicationMailer`
which sets the default layout.

*Andy Jeffries*

* `link_to` and `url_for` now generate URLs by default in templates.
Passing `only_path: false` is no longer needed.

Fixes #16497 and #16589.

*Xavier Noria*, *Richard Schneeman*

* Attachments can now be added while rendering the mail template.

Fixes #16974.

*Christian Felder*

* Add `#deliver_later` and `#deliver_now` methods and deprecate `#deliver` in
favor of `#deliver_now`. `#deliver_later` will enqueue a job to render and
deliver the mail instead of delivering it immediately. The job is enqueued
using the new Active Job framework in Rails and will use the queue that you
have configured in Rails.

*DHH*, *Abdelkader Boudih*, *Cristian Bica*

* `ActionMailer::Previews` are now class methods instead of instance methods.

*Cristian Bica*

* Deprecate `*_path` helpers in email views. They generated broken links in
email views and were not the intention of most developers. The `*_url`
helper is recommended instead.

*Richard Schneeman*

* Raise an exception when attachments are added after `mail` is called.
This is a safeguard to prevent invalid emails.

Fixes #16163.

*Yves Senn*

* Add `config.action_mailer.show_previews` configuration option.

This configuration option can be used to enable the mail preview in
environments other than development (such as staging).

Defaults to `true` in development and `false` elsewhere.

*Leonard Garvey*

* Allow preview interceptors to be registered through
`config.action_mailer.preview_interceptors`.

See #15739.

*Yves Senn*

Please check [4-1-stable](https://github.com/rails/rails/blob/4-1-stable/actionmailer/CHANGELOG.md)
for previous changes.
@@ -0,0 +1,21 @@
Copyright (c) 2004-2014 David Heinemeier Hansson

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@@ -0,0 +1,176 @@
= Action Mailer -- Easy email delivery and testing

Action Mailer is a framework for designing email service layers. These layers
are used to consolidate code for sending out forgotten passwords, welcome
wishes on signup, invoices for billing, and any other use case that requires
a written notification to either a person or another system.

Action Mailer is in essence a wrapper around Action Controller and the
Mail gem. It provides a way to make emails using templates in the same
way that Action Controller renders views using templates.

Additionally, an Action Mailer class can be used to process incoming email,
such as allowing a blog to accept new posts from an email (which could even
have been sent from a phone).

== Sending emails

The framework works by initializing any instance variables you want to be
available in the email template, followed by a call to +mail+ to deliver
the email.

This can be as simple as:

class Notifier < ActionMailer::Base
default from: 'system@loudthinking.com'

def welcome(recipient)
@recipient = recipient
mail(to: recipient,
subject: "[Signed up] Welcome #{recipient}")
end
end

The body of the email is created by using an Action View template (regular
ERB) that has the instance variables that are declared in the mailer action.

So the corresponding body template for the method above could look like this:

Hello there,

Mr. <%= @recipient %>

Thank you for signing up!

If the recipient was given as "david@loudthinking.com", the email
generated would look like this:

Date: Mon, 25 Jan 2010 22:48:09 +1100
From: system@loudthinking.com
To: david@loudthinking.com
Message-ID: <4b5d84f9dd6a5_7380800b81ac29578@void.loudthinking.com.mail>
Subject: [Signed up] Welcome david@loudthinking.com
Mime-Version: 1.0
Content-Type: text/plain;
charset="US-ASCII";
Content-Transfer-Encoding: 7bit

Hello there,

Mr. david@loudthinking.com

Thank you for signing up!

In order to send mails, you simply call the method and then call +deliver_now+ on the return value.

Calling the method returns a Mail Message object:

message = Notifier.welcome("david@loudthinking.com") # => Returns a Mail::Message object
message.deliver_now # => delivers the email

Or you can just chain the methods together like:

Notifier.welcome("david@loudthinking.com").deliver_now # Creates the email and sends it immediately

== Setting defaults

It is possible to set default values that will be used in every method in your
Action Mailer class. To implement this functionality, you just call the public
class method +default+ which you get for free from <tt>ActionMailer::Base</tt>.
This method accepts a Hash as the parameter. You can use any of the headers,
email messages have, like +:from+ as the key. You can also pass in a string as
the key, like "Content-Type", but Action Mailer does this out of the box for you,
so you won't need to worry about that. Finally, it is also possible to pass in a
Proc that will get evaluated when it is needed.

Note that every value you set with this method will get overwritten if you use the
same key in your mailer method.

Example:

class AuthenticationMailer < ActionMailer::Base
default from: "awesome@application.com", subject: Proc.new { "E-mail was generated at #{Time.now}" }
.....
end

== Receiving emails

To receive emails, you need to implement a public instance method called
+receive+ that takes an email object as its single parameter. The Action Mailer
framework has a corresponding class method, which is also called +receive+, that
accepts a raw, unprocessed email as a string, which it then turns into the email
object and calls the receive instance method.

Example:

class Mailman < ActionMailer::Base
def receive(email)
page = Page.find_by(address: email.to.first)
page.emails.create(
subject: email.subject, body: email.body
)

if email.has_attachments?
email.attachments.each do |attachment|
page.attachments.create({
file: attachment, description: email.subject
})
end
end
end
end

This Mailman can be the target for Postfix or other MTAs. In Rails, you would use
the runner in the trivial case like this:

rails runner 'Mailman.receive(STDIN.read)'

However, invoking Rails in the runner for each mail to be received is very
resource intensive. A single instance of Rails should be run within a daemon, if
it is going to process more than just a limited amount of email.

== Configuration

The Base class has the full list of configuration options. Here's an example:

ActionMailer::Base.smtp_settings = {
address: 'smtp.yourserver.com', # default: localhost
port: '25', # default: 25
user_name: 'user',
password: 'pass',
authentication: :plain # :plain, :login or :cram_md5
}


== Download and installation

The latest version of Action Mailer can be installed with RubyGems:

% [sudo] gem install actionmailer

Source code can be downloaded as part of the Rails project on GitHub

* https://github.com/rails/rails/tree/4-2-stable/actionmailer


== License

Action Mailer is released under the MIT license:

* http://www.opensource.org/licenses/MIT


== Support

API documentation is at

* http://api.rubyonrails.org

Bug reports can be filed for the Ruby on Rails project here:

* https://github.com/rails/rails/issues

Feature requests should be discussed on the rails-core mailing list here:

* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core

@@ -0,0 +1,58 @@
#--
# Copyright (c) 2004-2014 David Heinemeier Hansson
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++

require 'abstract_controller'
require 'action_mailer/version'

# Common Active Support usage in Action Mailer
require 'active_support/rails'
require 'active_support/core_ext/class'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/string/inflections'
require 'active_support/lazy_load_hooks'

module ActionMailer
extend ::ActiveSupport::Autoload

eager_autoload do
autoload :Collector
end

autoload :Base
autoload :DeliveryMethods
autoload :InlinePreviewInterceptor
autoload :MailHelper
autoload :Preview
autoload :Previews, 'action_mailer/preview'
autoload :TestCase
autoload :TestHelper
autoload :MessageDelivery
autoload :DeliveryJob
end

autoload :Mime, 'action_dispatch/http/mime_type'

ActiveSupport.on_load(:action_view) do
ActionView::Base.default_formats ||= Mime::SET.symbols
ActionView::Template::Types.delegate_to Mime
end

Large diffs are not rendered by default.

@@ -0,0 +1,30 @@
require 'abstract_controller/collector'
require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/array/extract_options'

module ActionMailer
class Collector
include AbstractController::Collector
attr_reader :responses

def initialize(context, &block)
@context = context
@responses = []
@default_render = block
end

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
alias :all :any

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
end
end
@@ -0,0 +1,13 @@
require 'active_job'

module ActionMailer
# The <tt>ActionMailer::DeliveryJob</tt> class is used when you
# want to send emails outside of the request-response cycle.
class DeliveryJob < ActiveJob::Base # :nodoc:
queue_as :mailers

def perform(mailer, mail_method, delivery_method, *args) # :nodoc:
mailer.constantize.public_send(mail_method, *args).send(delivery_method)
end
end
end
@@ -0,0 +1,84 @@
require 'tmpdir'

module ActionMailer
# This module handles everything related to mail delivery, from registering
# new delivery methods to configuring the mail object to be sent.
module DeliveryMethods
extend ActiveSupport::Concern

included do
class_attribute :delivery_methods, :delivery_method

# Do not make this inheritable, because we always want it to propagate
cattr_accessor :raise_delivery_errors
self.raise_delivery_errors = true

cattr_accessor :perform_deliveries
self.perform_deliveries = true

self.delivery_methods = {}.freeze
self.delivery_method = :smtp

add_delivery_method :smtp, Mail::SMTP,
address: "localhost",
port: 25,
domain: 'localhost.localdomain',
user_name: nil,
password: nil,
authentication: nil,
enable_starttls_auto: true

add_delivery_method :file, Mail::FileDelivery,
location: defined?(Rails.root) ? "#{Rails.root}/tmp/mails" : "#{Dir.tmpdir}/mails"

add_delivery_method :sendmail, Mail::Sendmail,
location: '/usr/sbin/sendmail',
arguments: '-i'

add_delivery_method :test, Mail::TestMailer
end

# Helpers for creating and wrapping delivery behavior, used by DeliveryMethods.
module ClassMethods
# Provides a list of emails that have been delivered by Mail::TestMailer
delegate :deliveries, :deliveries=, to: Mail::TestMailer

# Adds a new delivery method through the given class using the given
# symbol as alias and the default options supplied.
#
# add_delivery_method :sendmail, Mail::Sendmail,
# location: '/usr/sbin/sendmail',
# arguments: '-i -t'
def add_delivery_method(symbol, klass, default_options={})
class_attribute(:"#{symbol}_settings") unless respond_to?(:"#{symbol}_settings")
send(:"#{symbol}_settings=", default_options)
self.delivery_methods = delivery_methods.merge(symbol.to_sym => klass).freeze
end

def wrap_delivery_behavior(mail, method=nil, options=nil) # :nodoc:
method ||= self.delivery_method
mail.delivery_handler = self

case method
when NilClass
raise "Delivery method cannot be nil"
when Symbol
if klass = delivery_methods[method]
mail.delivery_method(klass, (send(:"#{method}_settings") || {}).merge(options || {}))
else
raise "Invalid delivery method #{method.inspect}"
end
else
mail.delivery_method(method)
end

mail.perform_deliveries = perform_deliveries
mail.raise_delivery_errors = raise_delivery_errors
end
end

def wrap_delivery_behavior!(*args) # :nodoc:
self.class.wrap_delivery_behavior(message, *args)
end
end
end
@@ -0,0 +1,15 @@
module ActionMailer
# Returns the version of the currently loaded Action Mailer as a <tt>Gem::Version</tt>
def self.gem_version
Gem::Version.new VERSION::STRING
end

module VERSION
MAJOR = 4
MINOR = 2
TINY = 7
PRE = "1"

STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
end
@@ -0,0 +1,61 @@
require 'base64'

module ActionMailer
# 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 a HTML email in a web browser.
#
# This interceptor is not enabled by default, to use it just register it like any
# other mailer preview interceptor:
#
# ActionMailer::Base.register_preview_interceptor(ActionMailer::InlinePreviewInterceptor)
#
class InlinePreviewInterceptor
PATTERN = /src=(?:"cid:[^"]+"|'cid:[^']+')/i

include Base64

def self.previewing_email(message) #:nodoc:
new(message).transform!
end

def initialize(message) #:nodoc:
@message = message
end

def transform! #:nodoc:
return message if html_part.blank?

html_source.gsub!(PATTERN) do |match|
if part = find_part(match[9..-2])
%[src="#{data_url(part)}"]
else
match
end
end

message
end

private
def message
@message
end

def html_part
@html_part ||= message.html_part
end

def html_source
html_part.body.raw_source
end

def data_url(part)
"data:#{part.mime_type};base64,#{strict_encode64(part.body.raw_source)}"
end

def find_part(cid)
message.all_parts.find{ |p| p.attachment? && p.cid == cid }
end
end
end
@@ -0,0 +1,39 @@
require 'active_support/log_subscriber'

module ActionMailer
# Implements the ActiveSupport::LogSubscriber for logging notifications when
# email is delivered and received.
class LogSubscriber < ActiveSupport::LogSubscriber
# An email was delivered.
def deliver(event)
info do
recipients = Array(event.payload[:to]).join(', ')
"\nSent mail to #{recipients} (#{event.duration.round(1)}ms)"
end

debug { event.payload[:mail] }
end

# An email was received.
def receive(event)
info { "\nReceived mail (#{event.duration.round(1)}ms)" }
debug { event.payload[:mail] }
end

# An email was generated.
def process(event)
debug do
mailer = event.payload[:mailer]
action = event.payload[:action]
"\n#{mailer}##{action}: processed outbound mail in #{event.duration.round(1)}ms"
end
end

# Use the logger configured for ActionMailer::Base
def logger
ActionMailer::Base.logger
end
end
end

ActionMailer::LogSubscriber.attach_to :action_mailer
@@ -0,0 +1,58 @@
module ActionMailer
# Provides helper methods for ActionMailer::Base that can be used for easily
# formatting messages, accessing mailer or message instances, and the
# attachments list.
module MailHelper
# Take the text and format it, indented two spaces for each line, and
# wrapped at 72 columns.
def block_format(text)
formatted = text.split(/\n\r?\n/).collect { |paragraph|
format_paragraph(paragraph)
}.join("\n\n")

# Make list points stand on their own line
formatted.gsub!(/[ ]*([*]+) ([^*]*)/) { " #{$1} #{$2.strip}\n" }
formatted.gsub!(/[ ]*([#]+) ([^#]*)/) { " #{$1} #{$2.strip}\n" }

formatted
end

# Access the mailer instance.
def mailer
@_controller
end

# Access the message instance.
def message
@_message
end

# Access the message attachments list.
def attachments
mailer.attachments
end

# Returns +text+ wrapped at +len+ columns and indented +indent+ 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"
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
end
end
@@ -0,0 +1,115 @@
require 'delegate'
require 'active_support/core_ext/string/filters'

module ActionMailer

# The <tt>ActionMailer::MessageDelivery</tt> class is used by
# <tt>ActionMailer::Base</tt> when creating a new mailer.
# <tt>MessageDelivery</tt> is a wrapper (+Delegator+ subclass) around a lazy
# created <tt>Mail::Message</tt>. You can get direct access to the
# <tt>Mail::Message</tt>, 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
class MessageDelivery < Delegator
def initialize(mailer, mail_method, *args) #:nodoc:
@mailer = mailer
@mail_method = mail_method
@args = args
end

def __getobj__ #:nodoc:
@obj ||= @mailer.send(:new, @mail_method, *@args).message
end

def __setobj__(obj) #:nodoc:
@obj = obj
end

# Returns the Mail::Message object
def message
__getobj__
end

# Enqueues the email to be delivered through Active Job. When the
# job runs it will send the email using +deliver_now!+. That means
# that the message will be sent bypassing checking +perform_deliveries+
# and +raise_delivery_errors+, so use with caution.
#
# Notifier.welcome(User.first).deliver_later!
# Notifier.welcome(User.first).deliver_later!(wait: 1.hour)
# Notifier.welcome(User.first).deliver_later!(wait_until: 10.hours.from_now)
#
# Options:
#
# * <tt>:wait</tt> - Enqueue the email to be delivered with a delay
# * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time
# * <tt>:queue</tt> - Enqueue the email on the specified queue
def deliver_later!(options={})
enqueue_delivery :deliver_now!, options
end

# Enqueues the email to be delivered through Active Job. When the
# job runs it will send the email using +deliver_now+.
#
# Notifier.welcome(User.first).deliver_later
# Notifier.welcome(User.first).deliver_later(wait: 1.hour)
# Notifier.welcome(User.first).deliver_later(wait_until: 10.hours.from_now)
#
# Options:
#
# * <tt>:wait</tt> - Enqueue the email to be delivered with a delay
# * <tt>:wait_until</tt> - Enqueue the email to be delivered at (after) a specific date / time
# * <tt>:queue</tt> - Enqueue the email on the specified queue
def deliver_later(options={})
enqueue_delivery :deliver_now, options
end

# Delivers an email without checking +perform_deliveries+ and +raise_delivery_errors+,
# so use with caution.
#
# Notifier.welcome(User.first).deliver_now!
#
def deliver_now!
message.deliver!
end

# Delivers an email:
#
# Notifier.welcome(User.first).deliver_now
#
def deliver_now
message.deliver
end

def deliver! #:nodoc:
ActiveSupport::Deprecation.warn(<<-MSG.squish)
`#deliver!` is deprecated and will be removed in Rails 5. Use
`#deliver_now!` to deliver immediately or `#deliver_later!` to
deliver through Active Job.
MSG

deliver_now!
end

def deliver #:nodoc:
ActiveSupport::Deprecation.warn(<<-MSG.squish)
`#deliver` is deprecated and will be removed in Rails 5. Use
`#deliver_now` to deliver immediately or `#deliver_later` to
deliver through Active Job.
MSG

deliver_now
end

private

def enqueue_delivery(delivery_method, options={})
args = @mailer.name, @mail_method.to_s, delivery_method.to_s, *@args
ActionMailer::DeliveryJob.set(options).perform_later(*args)
end
end
end
@@ -0,0 +1,118 @@
require 'active_support/descendants_tracker'

module ActionMailer
module Previews #:nodoc:
extend ActiveSupport::Concern

included do
# Set the location of mailer previews through app configuration:
#
# config.action_mailer.preview_path = "#{Rails.root}/lib/mailer_previews"
#
mattr_accessor :preview_path, instance_writer: false

# Enable or disable mailer previews through app configuration:
#
# config.action_mailer.show_previews = true
#
# Defaults to true for development environment
#
mattr_accessor :show_previews, instance_writer: false

# :nodoc:
mattr_accessor :preview_interceptors, instance_writer: false
self.preview_interceptors = []
end

module ClassMethods
# Register one or more Interceptors which will be called before mail is previewed.
def register_preview_interceptors(*interceptors)
interceptors.flatten.compact.each { |interceptor| register_preview_interceptor(interceptor) }
end

# 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 <tt>constantize</tt>d.
def register_preview_interceptor(interceptor)
preview_interceptor = case interceptor
when String, Symbol
interceptor.to_s.camelize.constantize
else
interceptor
end

unless preview_interceptors.include?(preview_interceptor)
preview_interceptors << preview_interceptor
end
end
end
end

class Preview
extend ActiveSupport::DescendantsTracker

class << self
# Returns all mailer preview classes
def all
load_previews if descendants.empty?
descendants
end

# 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.
def call(email)
preview = self.new
message = preview.public_send(email)
inform_preview_interceptors(message)
message
end

# Returns all of the available email previews
def emails
public_instance_methods(false).map(&:to_s).sort
end

# Returns true if the email exists
def email_exists?(email)
emails.include?(email)
end

# Returns true if the preview exists
def exists?(preview)
all.any?{ |p| p.preview_name == preview }
end

# Find a mailer preview by its underscored class name
def find(preview)
all.find{ |p| p.preview_name == preview }
end

# Returns the underscored name of the mailer preview without the suffix
def preview_name
name.sub(/Preview$/, '').underscore
end

protected
def load_previews #:nodoc:
if preview_path
Dir["#{preview_path}/**/*_preview.rb"].each{ |file| require_dependency file }
end
end

def preview_path #:nodoc:
Base.preview_path
end

def show_previews #:nodoc:
Base.show_previews
end

def inform_preview_interceptors(message) #:nodoc:
Base.preview_interceptors.each do |interceptor|
interceptor.previewing_email(message)
end
end
end
end
end
@@ -0,0 +1,64 @@
require 'active_job/railtie'
require "action_mailer"
require "rails"
require "abstract_controller/railties/routes_helpers"

module ActionMailer
class Railtie < Rails::Railtie # :nodoc:
config.action_mailer = ActiveSupport::OrderedOptions.new
config.eager_load_namespaces << ActionMailer

initializer "action_mailer.logger" do
ActiveSupport.on_load(:action_mailer) { self.logger ||= Rails.logger }
end

initializer "action_mailer.set_configs" do |app|
paths = app.config.paths
options = app.config.action_mailer

options.assets_dir ||= paths["public"].first
options.javascripts_dir ||= paths["public/javascripts"].first
options.stylesheets_dir ||= paths["public/stylesheets"].first
options.show_previews = Rails.env.development? if options.show_previews.nil?

if options.show_previews
options.preview_path ||= defined?(Rails.root) ? "#{Rails.root}/test/mailers/previews" : nil
end

# make sure readers methods get compiled
options.asset_host ||= app.config.asset_host
options.relative_url_root ||= app.config.relative_url_root

ActiveSupport.on_load(:action_mailer) do
include AbstractController::UrlFor
extend ::AbstractController::Railties::RoutesHelpers.with(app.routes, false)
include app.routes.mounted_helpers

register_interceptors(options.delete(:interceptors))
register_preview_interceptors(options.delete(:preview_interceptors))
register_observers(options.delete(:observers))

options.each { |k,v| send("#{k}=", v) }

if options.show_previews
app.routes.append do
get '/rails/mailers' => "rails/mailers#index"
get '/rails/mailers/*path' => "rails/mailers#preview"
end
end
end
end

initializer "action_mailer.compile_config_methods" do
ActiveSupport.on_load(:action_mailer) do
config.compile_methods! if config.respond_to?(:compile_methods!)
end
end

config.after_initialize do
if ActionMailer::Base.preview_path
ActiveSupport::Dependencies.autoload_paths << ActionMailer::Base.preview_path
end
end
end
end
@@ -0,0 +1,105 @@
require 'active_support/test_case'
require 'rails-dom-testing'

module ActionMailer
class NonInferrableMailerError < ::StandardError
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
end

class TestCase < ActiveSupport::TestCase
module Behavior
extend ActiveSupport::Concern

include ActiveSupport::Testing::ConstantLookup
include TestHelper
include Rails::Dom::Testing::Assertions::SelectorAssertions
include Rails::Dom::Testing::Assertions::DomAssertions

included do
class_attribute :_mailer_class
setup :initialize_test_deliveries
setup :set_expected_mail
teardown :restore_test_deliveries
end

module ClassMethods
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

def mailer_class
if mailer = self._mailer_class
mailer
else
tests determine_default_mailer(name)
end
end

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
end

protected

def initialize_test_deliveries
set_delivery_method :test
@old_perform_deliveries = ActionMailer::Base.perform_deliveries
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.deliveries.clear
end

def restore_test_deliveries
restore_delivery_method
ActionMailer::Base.perform_deliveries = @old_perform_deliveries
end

def set_delivery_method(method)
@old_delivery_method = ActionMailer::Base.delivery_method
ActionMailer::Base.delivery_method = method
end

def restore_delivery_method
ActionMailer::Base.deliveries.clear
ActionMailer::Base.delivery_method = @old_delivery_method
end

def set_expected_mail
@expected = Mail.new
@expected.content_type ["text", "plain", { "charset" => charset }]
@expected.mime_version = '1.0'
end

private

def charset
"UTF-8"
end

def encode(subject)
Mail::Encodings.q_value_encode(subject, charset)
end

def read_fixture(action)
IO.readlines(File.join(Rails.root, 'test', 'fixtures', self.class.mailer_class.name.underscore, action))
end
end

include Behavior
end
end
@@ -0,0 +1,62 @@
module ActionMailer
# Provides helper methods for testing Action Mailer, including #assert_emails
# and #assert_no_emails
module TestHelper
# Asserts that the number of emails sent matches the given number.
#
# def test_emails
# assert_emails 0
# ContactMailer.welcome.deliver_now
# assert_emails 1
# ContactMailer.welcome.deliver_now
# assert_emails 2
# end
#
# If a block is passed, that block should cause the specified number of
# emails to be sent.
#
# def test_emails_again
# assert_emails 1 do
# ContactMailer.welcome.deliver_now
# end
#
# assert_emails 2 do
# ContactMailer.welcome.deliver_now
# ContactMailer.welcome.deliver_now
# end
# end
def assert_emails(number)
if block_given?
original_count = ActionMailer::Base.deliveries.size
yield
new_count = ActionMailer::Base.deliveries.size
assert_equal number, new_count - original_count, "#{number} emails expected, but #{new_count - original_count} were sent"
else
assert_equal number, ActionMailer::Base.deliveries.size
end
end

# Assert 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
def assert_no_emails(&block)
assert_emails 0, &block
end
end
end
@@ -0,0 +1,9 @@
require_relative 'gem_version'

module ActionMailer
# Returns the version of the currently loaded Action Mailer as a
# <tt>Gem::Version</tt>.
def self.version
gem_version
end
end
@@ -0,0 +1,17 @@
Description:
============
Stubs out a new mailer and its views. Passes the mailer name, either
CamelCased or under_scored, and an optional list of emails as arguments.

This generates a mailer class in app/mailers and invokes your template
engine and test framework generators.

Example:
========
rails generate mailer Notifications signup forgot_password invoice

creates a Notifications mailer class, views, and test:
Mailer: app/mailers/notifications.rb
Views: app/views/notifications/signup.text.erb [...]
Test: test/mailers/notifications_test.rb

@@ -0,0 +1,19 @@
module Rails
module Generators
class MailerGenerator < NamedBase
source_root File.expand_path("../templates", __FILE__)

argument :actions, type: :array, default: [], banner: "method method"
check_class_collision

def create_mailer_file
template "mailer.rb", File.join('app/mailers', class_path, "#{file_name}.rb")
if self.behavior == :invoke
template "application_mailer.rb", 'app/mailers/application_mailer.rb'
end
end

hook_for :template_engine, :test_framework
end
end
end
@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: "from@example.com"
layout 'mailer'
end
@@ -0,0 +1,17 @@
<% module_namespacing do -%>
class <%= class_name %> < ApplicationMailer
<% actions.each do |action| -%>
# Subject can be set in your I18n file at config/locales/en.yml
# with the following lookup:
#
# en.<%= file_path.tr("/",".") %>.<%= action %>.subject
#
def <%= action %>
@greeting = "Hi"
mail to: "to@example.org"
end
<% end -%>
end
<% end -%>

Large diffs are not rendered by default.

@@ -0,0 +1,21 @@
Copyright (c) 2004-2014 David Heinemeier Hansson

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@@ -0,0 +1,58 @@
= Action Pack -- From request to response

Action Pack is a framework for handling and responding to web requests. It
provides mechanisms for *routing* (mapping request URLs to actions), defining
*controllers* that implement actions, and generating responses by rendering
*views*, which are templates of various formats. In short, Action Pack
provides the view and controller layers in the MVC paradigm.

It consists of several modules:

* Action Dispatch, which parses information about the web request, handles
routing as defined by the user, and does advanced processing related to HTTP
such as MIME-type negotiation, decoding parameters in POST, PATCH, or PUT bodies,
handling HTTP caching logic, cookies and sessions.

* Action Controller, which provides a base controller class that can be
subclassed to implement filters and actions to handle requests. The result
of an action is typically content generated from views.

With the Ruby on Rails framework, users only directly interface with the
Action Controller module. Necessary Action Dispatch functionality is activated
by default and Action View rendering is implicitly triggered by Action
Controller. However, these modules are designed to function on their own and
can be used outside of Rails.


== Download and installation

The latest version of Action Pack can be installed with RubyGems:

% [sudo] gem install actionpack

Source code can be downloaded as part of the Rails project on GitHub

* https://github.com/rails/rails/tree/4-2-stable/actionpack


== License

Action Pack is released under the MIT license:

* http://www.opensource.org/licenses/MIT


== Support

API documentation is at

* http://api.rubyonrails.org

Bug reports can be filed for the Ruby on Rails project here:

* https://github.com/rails/rails/issues

Feature requests should be discussed on the rails-core mailing list here:

* https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core

@@ -0,0 +1,20 @@
require 'action_pack'
require 'active_support/rails'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/anonymous'
require 'active_support/i18n'

module AbstractController
extend ActiveSupport::Autoload

autoload :Base
autoload :Callbacks
autoload :Collector
autoload :DoubleRenderError, "abstract_controller/rendering"
autoload :Helpers
autoload :Logger
autoload :Rendering
autoload :Translation
autoload :AssetPaths
autoload :UrlFor
end
@@ -0,0 +1,10 @@
module AbstractController
module AssetPaths #:nodoc:
extend ActiveSupport::Concern

included do
config_accessor :asset_host, :assets_dir, :javascripts_dir,
:stylesheets_dir, :default_asset_host_protocol, :relative_url_root
end
end
end
@@ -0,0 +1,269 @@
require 'erubis'
require 'set'
require 'active_support/configurable'
require 'active_support/descendants_tracker'
require 'active_support/core_ext/module/anonymous'

module AbstractController
class Error < StandardError #:nodoc:
end

# Raised when a non-existing controller action is triggered.
class ActionNotFound < StandardError
end

# <tt>AbstractController::Base</tt> 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.
class Base
attr_internal :response_body
attr_internal :action_name
attr_internal :formats

include ActiveSupport::Configurable
extend ActiveSupport::DescendantsTracker

undef_method :not_implemented
class << self
attr_reader :abstract
alias_method :abstract?, :abstract

# Define a controller as abstract. See internal_methods for more
# details.
def abstract!
@abstract = true
end

def inherited(klass) # :nodoc:
# Define the abstract ivar on subclasses so that we don't get
# uninitialized ivar warnings
unless klass.instance_variable_defined?(:@abstract)
klass.instance_variable_set(:@abstract, false)
end
super
end

# 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)
def internal_methods
controller = self

controller = controller.superclass until controller.abstract?
controller.public_instance_methods(true)
end

# The list of hidden actions. Defaults to an empty array.
# This can be modified by other modules or subclasses
# to specify particular actions as hidden.
#
# ==== Returns
# * <tt>Array</tt> - An array of method names that should not be considered actions.
def hidden_actions
[]
end

# 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. Finally, #hidden_actions are removed.
#
# ==== Returns
# * <tt>Set</tt> - A set of all methods that should be considered actions.
def action_methods
@action_methods ||= begin
# All public instance methods of this class, including ancestors
methods = (public_instance_methods(true) -
# Except for public instance methods of Base and its ancestors
internal_methods +
# Be sure to include shadowed public instance methods of this class
public_instance_methods(false)).uniq.map { |x| x.to_s } -
# And always exclude explicitly hidden actions
hidden_actions.to_a

# Clear out AS callback method pollution
Set.new(methods.reject { |method| method =~ /_one_time_conditions/ })
end
end

# 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
def clear_action_methods!
@action_methods = nil
end

# Returns the full controller name, underscored, without the ending Controller.
# For instance, MyApp::MyPostsController would return "my_app/my_posts" for
# controller_path.
#
# ==== Returns
# * <tt>String</tt>
def controller_path
@controller_path ||= name.sub(/Controller$/, '').underscore unless anonymous?
end

# Refresh the cached action_methods when a new action_method is added.
def method_added(name)
super
clear_action_methods!
end
end

abstract!

# 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
# * <tt>self</tt>
def process(action, *args)
@_action_name = action.to_s

unless action_name = _find_action_name(@_action_name)
raise ActionNotFound, "The action '#{action}' could not be found for #{self.class.name}"
end

@_response_body = nil

process_action(action_name, *args)
end

# Delegates to the class' #controller_path
def controller_path
self.class.controller_path
end

# Delegates to the class' #action_methods
def action_methods
self.class.action_methods
end

# Returns true if a method for the action is available and
# can be dispatched, false otherwise.
#
# Notice that <tt>action_methods.include?("foo")</tt> may return
# false and <tt>available_action?("foo")</tt> returns true because
# this method considers actions that are also available
# through other means, for example, implicit render ones.
#
# ==== Parameters
# * <tt>action_name</tt> - The name of an action to be tested
#
# ==== Returns
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
def available_action?(action_name)
_find_action_name(action_name).present?
end

# 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.
def self.supports_path?
true
end

private

# Returns true if the name can be considered an action because
# it has a method defined in the controller.
#
# ==== Parameters
# * <tt>name</tt> - The name of an action to be tested
#
# ==== Returns
# * <tt>TrueClass</tt>, <tt>FalseClass</tt>
#
# :api: private
def action_method?(name)
self.class.action_methods.include?(name)
end

# Call the action. Override this in a subclass to modify the
# behavior around processing an action. This, and not #process,
# is the intended way to override action dispatching.
#
# Notice that the first argument is the method to be dispatched
# which is *not* necessarily the same as the action name.
def process_action(method_name, *args)
send_action(method_name, *args)
end

# Actually call the method associated with the action. Override
# this method if you wish to change how action methods are called,
# not to add additional behavior around it. For example, you would
# override #send_action if you want to inject arguments into the
# method.
alias send_action send

# If the action name was not found, but a method called "action_missing"
# was found, #method_for_action will return "_handle_action_missing".
# This method calls #action_missing with the current action name.
def _handle_action_missing(*args)
action_missing(@_action_name, *args)
end

# Takes an action name and returns the name of the method that will
# handle the action.
#
# It checks if the action name is valid and returns false otherwise.
#
# See method_for_action for more information.
#
# ==== Parameters
# * <tt>action_name</tt> - An action name to find a method name for
#
# ==== Returns
# * <tt>string</tt> - The name of the method that handles the action
# * false - No valid method name could be found.
# Raise AbstractController::ActionNotFound.
def _find_action_name(action_name)
_valid_action_name?(action_name) && method_for_action(action_name)
end

# Takes an action name and returns the name of the method that will
# handle the action. In normal cases, this method returns the same
# name as it receives. By default, if #method_for_action receives
# a name that is not an action, it will look for an #action_missing
# method and return "_handle_action_missing" if one is found.
#
# Subclasses may override this method to add additional conditions
# that should be considered an action. For instance, an HTTP controller
# with a template matching the action name is considered to exist.
#
# If you override this method to handle additional cases, you may
# also provide a method (like _handle_method_missing) to handle
# the case.
#
# If none of these conditions are true, and method_for_action
# returns nil, an AbstractController::ActionNotFound exception will be raised.
#
# ==== Parameters
# * <tt>action_name</tt> - An action name to find a method name for
#
# ==== Returns
# * <tt>string</tt> - The name of the method that handles the action
# * <tt>nil</tt> - No method name could be found.
def method_for_action(action_name)
if action_method?(action_name)
action_name
elsif respond_to?(:action_missing, true)
"_handle_action_missing"
end
end

# Checks if the action name is valid and returns false otherwise.
def _valid_action_name?(action_name)
!action_name.to_s.include? File::SEPARATOR
end
end
end
@@ -0,0 +1,196 @@
module AbstractController
module Callbacks
extend ActiveSupport::Concern

# Uses ActiveSupport::Callbacks as the base functionality. For
# more details on the whole callback system, read the documentation
# for ActiveSupport::Callbacks.
include ActiveSupport::Callbacks

included do
define_callbacks :process_action,
terminator: ->(controller,_) { controller.response_body },
skip_after_callbacks_if_terminated: true
end

# Override AbstractController::Base's process_action to run the
# process_action callbacks around the normal behavior.
def process_action(*args)
run_callbacks(:process_action) do
super
end
end

module ClassMethods
# If :only or :except are used, convert the options into the
# :unless and :if options of ActiveSupport::Callbacks.
# The basic idea is that :only => :index gets converted to
# :if => proc {|c| c.action_name == "index" }.
#
# ==== Options
# * <tt>only</tt> - The callback should be run only for this action
# * <tt>except</tt> - The callback should be run for all actions except this action
def _normalize_callback_options(options)
_normalize_callback_option(options, :only, :if)
_normalize_callback_option(options, :except, :unless)
end

def _normalize_callback_option(options, from, to) # :nodoc:
if from = options[from]
from = Array(from).map {|o| "action_name == '#{o}'"}.join(" || ")
options[to] = Array(options[to]).unshift(from)
end
end

# Skip before, after, and around action callbacks matching any of the names.
#
# ==== Parameters
# * <tt>names</tt> - A list of valid names that could be used for
# callbacks. Note that skipping uses Ruby equality, so it's
# impossible to skip a callback defined using an anonymous proc
# using #skip_action_callback
def skip_action_callback(*names)
skip_before_action(*names)
skip_after_action(*names)
skip_around_action(*names)
end
alias_method :skip_filter, :skip_action_callback

# 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
# * <tt>callbacks</tt> - An array of callbacks, with an optional
# options hash as the last parameter.
# * <tt>block</tt> - A proc that should be added to the callbacks.
#
# ==== Block Parameters
# * <tt>name</tt> - The callback to be added
# * <tt>options</tt> - A hash of options to be used when adding the callback
def _insert_callbacks(callbacks, block = nil)
options = callbacks.extract_options!
_normalize_callback_options(options)
callbacks.push(block) if block
callbacks.each do |callback|
yield callback, options
end
end

##
# :method: before_action
#
# :call-seq: before_action(names, block)
#
# Append a callback before actions. See _insert_callbacks for parameter details.

##
# :method: prepend_before_action
#
# :call-seq: prepend_before_action(names, block)
#
# Prepend a callback before actions. See _insert_callbacks for parameter details.

##
# :method: skip_before_action
#
# :call-seq: skip_before_action(names)
#
# Skip a callback before actions. See _insert_callbacks for parameter details.

##
# :method: append_before_action
#
# :call-seq: append_before_action(names, block)
#
# Append a callback before actions. See _insert_callbacks for parameter details.

##
# :method: after_action
#
# :call-seq: after_action(names, block)
#
# Append a callback after actions. See _insert_callbacks for parameter details.

##
# :method: prepend_after_action
#
# :call-seq: prepend_after_action(names, block)
#
# Prepend a callback after actions. See _insert_callbacks for parameter details.

##
# :method: skip_after_action
#
# :call-seq: skip_after_action(names)
#
# Skip a callback after actions. See _insert_callbacks for parameter details.

##
# :method: append_after_action
#
# :call-seq: append_after_action(names, block)
#
# Append a callback after actions. See _insert_callbacks for parameter details.

##
# :method: around_action
#
# :call-seq: around_action(names, block)
#
# Append a callback around actions. See _insert_callbacks for parameter details.

##
# :method: prepend_around_action
#
# :call-seq: prepend_around_action(names, block)
#
# Prepend a callback around actions. See _insert_callbacks for parameter details.

##
# :method: skip_around_action
#
# :call-seq: skip_around_action(names)
#
# Skip a callback around actions. See _insert_callbacks for parameter details.

##
# :method: append_around_action
#
# :call-seq: 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.
[:before, :after, :around].each do |callback|
define_method "#{callback}_action" do |*names, &blk|
_insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, callback, name, options)
end
end
alias_method :"#{callback}_filter", :"#{callback}_action"

define_method "prepend_#{callback}_action" do |*names, &blk|
_insert_callbacks(names, blk) do |name, options|
set_callback(:process_action, callback, name, options.merge(:prepend => true))
end
end
alias_method :"prepend_#{callback}_filter", :"prepend_#{callback}_action"

# Skip a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
define_method "skip_#{callback}_action" do |*names|
_insert_callbacks(names) do |name, options|
skip_callback(:process_action, callback, name, options)
end
end
alias_method :"skip_#{callback}_filter", :"skip_#{callback}_action"

# *_action is the same as append_*_action
alias_method :"append_#{callback}_action", :"#{callback}_action"
alias_method :"append_#{callback}_filter", :"#{callback}_action"
end
end
end
end
@@ -0,0 +1,46 @@
require "action_dispatch/http/mime_type"

module AbstractController
module Collector
def self.generate_method_for_mime(mime)
sym = mime.is_a?(Symbol) ? mime : mime.to_sym
const = sym.upcase
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{sym}(*args, &block) # def html(*args, &block)
custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block)
end # end
RUBY
end

Mime::SET.each do |mime|
generate_method_for_mime(mime)
end

Mime::Type.register_callback do |mime|
generate_method_for_mime(mime) unless self.instance_methods.include?(mime.to_sym)
end

protected

def method_missing(symbol, &block)
const_name = symbol.upcase

unless Mime.const_defined?(const_name)
raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
"http://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
"If you meant to respond to a variant like :tablet or :phone, not a custom format, " \
"be sure to nest your variant response within a format response: " \
"format.html { |html| html.tablet { ... } }"
end

mime_constant = Mime.const_get(const_name)

if Mime::SET.include?(mime_constant)
AbstractController::Collector.generate_method_for_mime(mime_constant)
send(symbol, &block)
else
super
end
end
end
end
@@ -0,0 +1,194 @@
require 'active_support/dependencies'

module AbstractController
module Helpers
extend ActiveSupport::Concern

included do
class_attribute :_helpers
self._helpers = Module.new

class_attribute :_helper_methods
self._helper_methods = Array.new
end

class MissingHelperError < LoadError
def initialize(error, path)
@error = error
@path = "helpers/#{path}.rb"
set_backtrace error.backtrace

if error.path =~ /^#{path}(\.rb)?$/
super("Missing helper file helpers/%s.rb" % path)
else
raise error
end
end
end

module ClassMethods
# 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.
def inherited(klass)
helpers = _helpers
klass._helpers = Module.new { include helpers }
klass.class_eval { default_helper_module! } unless klass.anonymous?
super
end

# Declare a controller method as a helper. For example, the following
# makes the +current_user+ controller method available to the view:
# class ApplicationController < ActionController::Base
# helper_method :current_user, :logged_in?
#
# def current_user
# @current_user ||= User.find_by(id: session[:user])
# end
#
# def logged_in?
# current_user != nil
# end
# end
#
# In a view:
# <% if logged_in? -%>Welcome, <%= current_user.name %><% end -%>
#
# ==== Parameters
# * <tt>method[, method]</tt> - A name or names of a method on the controller
# to be made available on the view.
def helper_method(*meths)
meths.flatten!
self._helper_methods += meths

meths.each do |meth|
_helpers.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1
def #{meth}(*args, &blk) # def current_user(*args, &blk)
controller.send(%(#{meth}), *args, &blk) # controller.send(:current_user, *args, &blk)
end # end
ruby_eval
end
end

# The +helper+ class method can take a series of helper module names, a block, or both.
#
# ==== Options
# * <tt>*args</tt> - Module, Symbol, String
# * <tt>block</tt> - A block defining helper methods
#
# When the argument is a module it will be included directly in the template class.
# helper FooHelper # => includes FooHelper
#
# When the argument is a string or symbol, the method will provide the "_helper" suffix, require the file
# and include the module in the template class. The second form illustrates how to include custom helpers
# when working with namespaced controllers, or other cases where the file containing the helper definition is not
# in one of Rails' standard load paths:
# helper :foo # => requires 'foo_helper' and includes FooHelper
# helper 'resources/foo' # => requires 'resources/foo_helper' and includes Resources::FooHelper
#
# Additionally, the +helper+ class method can receive and evaluate a block, making the methods defined available
# to the template.
#
# # One line
# helper { def hello() "Hello, world!" end }
#
# # Multi-line
# helper do
# def foo(bar)
# "#{bar} is the very best"
# end
# end
#
# Finally, all the above styles can be mixed together, and the +helper+ method can be invoked with a mix of
# +symbols+, +strings+, +modules+ and blocks.
#
# helper(:three, BlindHelper) { def mice() 'mice' end }
#
def helper(*args, &block)
modules_for_helpers(args).each do |mod|
add_template_helper(mod)
end

_helpers.module_eval(&block) if block_given?
end

# Clears up all existing helpers in this class, only keeping the helper
# with the same name as this class.
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

# Returns a list of modules, normalized from the acceptable kinds of
# helpers with the following behavior:
#
# String or Symbol:: :FooBar or "FooBar" becomes "foo_bar_helper",
# and "foo_bar_helper.rb" is loaded using require_dependency.
#
# Module:: No further processing
#
# After loading the appropriate files, the corresponding modules
# are returned.
#
# ==== Parameters
# * <tt>args</tt> - An array of helpers
#
# ==== Returns
# * <tt>Array</tt> - A normalized list of modules for the list of
# helpers provided.
def modules_for_helpers(args)
args.flatten.map! do |arg|
case arg
when String, Symbol
file_name = "#{arg.to_s.underscore}_helper"
begin
require_dependency(file_name)
rescue LoadError => e
raise AbstractController::Helpers::MissingHelperError.new(e, file_name)
end

mod_name = file_name.camelize
begin
mod_name.constantize
rescue LoadError
# dependencies.rb gives a similar error message but its wording is
# not as clear because it mentions autoloading. To the user all it
# matters is that a helper module couldn't be loaded, autoloading
# is an internal mechanism that should not leak.
raise NameError, "Couldn't find #{mod_name}, expected it to be defined in helpers/#{file_name}.rb"
end
when Module
arg
else
raise ArgumentError, "helper must be a String, Symbol, or Module"
end
end
end

private
# Makes all the (instance) methods in the helper module available to templates
# rendered through this controller.
#
# ==== Parameters
# * <tt>module</tt> - The module to include into the current helper module
# for the class
def add_template_helper(mod)
_helpers.module_eval { include mod }
end

def default_helper_module!
module_name = name.sub(/Controller$/, '')
module_path = module_name.underscore
helper module_path
rescue MissingSourceFile => e
raise e unless e.is_missing? "helpers/#{module_path}_helper"
rescue NameError => e
raise e unless e.missing_name? "#{module_name}Helper"
end
end
end
end
@@ -0,0 +1,12 @@
require "active_support/benchmarkable"

module AbstractController
module Logger #:nodoc:
extend ActiveSupport::Concern

included do
config_accessor :logger
include ActiveSupport::Benchmarkable
end
end
end
@@ -0,0 +1,18 @@
module AbstractController
module Railties
module RoutesHelpers
def self.with(routes, include_path_helpers = true)
Module.new do
define_method(:inherited) do |klass|
super(klass)
if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_routes_url_helpers) }
klass.send(:include, namespace.railtie_routes_url_helpers(include_path_helpers))
else
klass.send(:include, routes.url_helpers(include_path_helpers))
end
end
end
end
end
end
end
@@ -0,0 +1,126 @@
require 'active_support/concern'
require 'active_support/core_ext/class/attribute'
require 'action_view'
require 'action_view/view_paths'
require 'set'

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

def initialize(message = nil)
super(message || DEFAULT_MESSAGE)
end
end

module Rendering
extend ActiveSupport::Concern
include ActionView::ViewPaths

# Normalize arguments, options and then delegates render_to_body and
# sticks the result in self.response_body.
# :api: public
def render(*args, &block)
options = _normalize_render(*args, &block)
self.response_body = render_to_body(options)
_process_format(rendered_format, options) if rendered_format
self.response_body
end

# Raw rendering of a template to a string.
#
# It is similar to render, except that it does not
# set the response_body and it should be guaranteed
# to always return a string.
#
# If a component extends the semantics of response_body
# (as Action Controller extends it to be anything that
# responds to the method each), this method needs to be
# overridden in order to still return a string.
# :api: plugin
def render_to_string(*args, &block)
options = _normalize_render(*args, &block)
render_to_body(options)
end

# Performs the actual template rendering.
# :api: public
def render_to_body(options = {})
end

# Returns Content-Type of rendered content
# :api: public
def rendered_format
Mime::TEXT
end

DEFAULT_PROTECTED_INSTANCE_VARIABLES = Set.new %w(
@_action_name @_response_body @_formats @_prefixes @_config
@_view_context_class @_view_renderer @_lookup_context
@_routes @_db_runtime
).map(&:to_sym)

# This method should return a hash with assigns.
# You can overwrite this configuration per controller.
# :api: public
def view_assigns
protected_vars = _protected_ivars
variables = instance_variables

variables.reject! { |s| protected_vars.include? s }
variables.each_with_object({}) { |name, hash|
hash[name.slice(1, name.length)] = instance_variable_get(name)
}
end

# Normalize args by converting render "foo" to render :action => "foo" and
# render "foo/bar" to render :file => "foo/bar".
# :api: plugin
def _normalize_args(action=nil, options={})
if action.respond_to?(:permitted?)
if action.permitted?
action
else
raise ArgumentError, "render parameters are not permitted"
end
elsif action.is_a?(Hash)
action
else
options
end
end

# Normalize options.
# :api: plugin
def _normalize_options(options)
options
end

# Process extra options.
# :api: plugin
def _process_options(options)
options
end

# Process the rendered format.
# :api: private
def _process_format(format, options = {})
end

# Normalize args and options.
# :api: private
def _normalize_render(*args, &block)
options = _normalize_args(*args, &block)
#TODO: remove defined? when we restore AP <=> AV dependency
if defined?(request) && request && request.variant.present?
options[:variant] = request.variant
end
_normalize_options(options)
options
end

def _protected_ivars # :nodoc:
DEFAULT_PROTECTED_INSTANCE_VARIABLES
end
end
end
@@ -0,0 +1,28 @@
module AbstractController
module Translation
# Delegates to <tt>I18n.translate</tt>. Also aliased as <tt>t</tt>.
#
# When the given key starts with a period, it will be scoped by the current
# controller and action. So if you call <tt>translate(".foo")</tt> from
# <tt>PeopleController#index</tt>, it will convert the call to
# <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
# to translate many keys within the same controller / action and gives you a
# simple framework for scoping them consistently.
def translate(*args)
key = args.first
if key.is_a?(String) && (key[0] == '.')
key = "#{ controller_path.tr('/', '.') }.#{ action_name }#{ key }"
args[0] = key
end

I18n.translate(*args)
end
alias :t :translate

# Delegates to <tt>I18n.localize</tt>. Also aliased as <tt>l</tt>.
def localize(*args)
I18n.localize(*args)
end
alias :l :localize
end
end
@@ -0,0 +1,33 @@
module AbstractController
# Includes +url_for+ into the host class (e.g. an abstract controller or mailer). The class
# has to provide a +RouteSet+ by implementing the <tt>_routes</tt> methods. Otherwise, an
# exception will be raised.
#
# Note that this module is completely decoupled from HTTP - the only requirement is a valid
# <tt>_routes</tt> implementation.
module UrlFor
extend ActiveSupport::Concern
include ActionDispatch::Routing::UrlFor

def _routes
raise "In order to use #url_for, you must include routing helpers explicitly. " \
"For instance, `include Rails.application.routes.url_helpers`."
end

module ClassMethods
def _routes
nil
end

def action_methods
@action_methods ||= begin
if _routes
super - _routes.named_routes.helper_names
else
super
end
end
end
end
end
end
@@ -0,0 +1,58 @@
require 'active_support/rails'
require 'abstract_controller'
require 'action_dispatch'
require 'action_controller/metal/live'
require 'action_controller/metal/strong_parameters'

module ActionController
extend ActiveSupport::Autoload

autoload :Base
autoload :Caching
autoload :Metal
autoload :Middleware

autoload_under "metal" do
autoload :Compatibility
autoload :ConditionalGet
autoload :Cookies
autoload :DataStreaming
autoload :EtagWithTemplateDigest
autoload :Flash
autoload :ForceSSL
autoload :Head
autoload :Helpers
autoload :HideActions
autoload :HttpAuthentication
autoload :ImplicitRender
autoload :Instrumentation
autoload :MimeResponds
autoload :ParamsWrapper
autoload :RackDelegation
autoload :Redirecting
autoload :Renderers
autoload :Rendering
autoload :RequestForgeryProtection
autoload :Rescue
autoload :Streaming
autoload :StrongParameters
autoload :Testing
autoload :UrlFor
end

autoload :TestCase, 'action_controller/test_case'
autoload :TemplateAssertions, 'action_controller/test_case'

def self.eager_load!
super
ActionController::Caching.eager_load!
end
end

# Common Active Support usage in Action Controller
require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/load_error'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/name_error'
require 'active_support/core_ext/uri'
require 'active_support/inflector'