1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Another refactoring on AM. body is deprecated, use render instead.

This commit is contained in:
José Valim 2009-10-21 21:05:55 -02:00 committed by Yehuda Katz
parent 0396004861
commit 418c3f801c
4 changed files with 91 additions and 116 deletions

View file

@ -32,6 +32,7 @@ module ActionMailer
end
autoload :AdvAttrAccessor, 'action_mailer/adv_attr_accessor'
autoload :DeprecatedBody, 'action_mailer/deprecated_body'
autoload :Base, 'action_mailer/base'
autoload :DeliveryMethod, 'action_mailer/delivery_method'
autoload :Part, 'action_mailer/part'

View file

@ -263,6 +263,8 @@ module ActionMailer #:nodoc:
include ActionController::UrlWriter
end
include ActionMailer::DeprecatedBody
private_class_method :new #:nodoc:
class_inheritable_accessor :view_paths
@ -304,16 +306,11 @@ module ActionMailer #:nodoc:
cattr_accessor :default_implicit_parts_order
cattr_reader :protected_instance_variables
@@protected_instance_variables = %w(@body)
@@protected_instance_variables = []
# Specify the BCC addresses for the message
adv_attr_accessor :bcc
# Define the body of the message. This is either a Hash (in which case it
# specifies the variables to pass to the template when it is rendered),
# or a string, in which case it specifies the actual text of the message.
adv_attr_accessor :body
# Specify the CC addresses for the message.
adv_attr_accessor :cc
@ -358,33 +355,27 @@ module ActionMailer #:nodoc:
# have multiple mailer methods share the same template.
adv_attr_accessor :template
# The mail and action_name instances referenced by this mailer.
attr_reader :mail, :action_name
# Where the response body is stored.
attr_internal :response_body
# Override the mailer name, which defaults to an inflected version of the
# mailer's class name. If you want to use a template in a non-standard
# location, you can use this to specify that location.
attr_writer :mailer_name
def mailer_name(value = nil)
if value
self.mailer_name = value
@mailer_name = value
else
self.class.mailer_name
@mailer_name || self.class.mailer_name
end
end
def mailer_name=(value)
self.class.mailer_name = value
end
# The mail object instance referenced by this mailer.
attr_reader :mail
attr_reader :template_name, :default_template_name, :action_name
attr_internal :response_body
def controller_path
self.class.controller_path
end
def formats
[:"*/*"]
end
# Alias controller_path to mailer_name so render :partial in views work.
alias :controller_path :mailer_name
class << self
attr_writer :mailer_name
@ -393,10 +384,6 @@ module ActionMailer #:nodoc:
@mailer_name ||= name.underscore
end
# for ActionView compatibility
alias_method :controller_name, :mailer_name
alias_method :controller_path, :mailer_name
def respond_to?(method_symbol, include_private = false) #:nodoc:
matches_dynamic_method?(method_symbol) || super
end
@ -472,58 +459,8 @@ module ActionMailer #:nodoc:
initialize_defaults(method_name)
__send__(method_name, *parameters)
# Check if render was called.
@body = self.response_body if @body.is_a?(Hash) && @body.empty?
# If an explicit, textual body has not been set, we check assumptions.
unless String === @body
# TODO Fix me. Deprecate assigns to be given as a :body hash
if @body.is_a?(Hash)
@body.each do |k, v|
instance_variable_set(:"@#{k}", v)
end
end
# First, we look to see if there are any likely templates that match,
# which include the content-type in their file name (i.e.,
# "the_template_file.text.html.erb", etc.). Only do this if parts
# have not already been specified manually.
# if @parts.empty?
template_root.find_all(@template, {}, template_path).each do |template|
@parts << Part.new(
:content_type => template.mime_type ? template.mime_type.to_s : "text/plain",
:disposition => "inline",
:charset => charset,
:body => render_to_body(:_template => template)
)
end
if @parts.size > 1
@content_type = "multipart/alternative" if @content_type !~ /^multipart/
@parts = sort_parts(@parts, @implicit_parts_order)
end
# end
# Then, if there were such templates, we check to see if we ought to
# also render a "normal" template (without the content type). If a
# normal template exists (or if there were no implicit parts) we render
# it.
# ====
# TODO: Revisit this
# template_exists = @parts.empty?
# template_exists ||= template_root.find("#{mailer_name}/#{@template}")
# @body = render_message(@template, @body) if template_exists
# Finally, if there are other message parts and a textual body exists,
# we shift it onto the front of the parts and set the body to nil (so
# that create_mail doesn't try to render it in addition to the parts).
# ====
# TODO: Revisit this
# if !@parts.empty? && String === @body
# @parts.unshift Part.new(:charset => charset, :body => @body)
# @body = nil
# end
end
# Create e-mail parts
create_parts
# If this is a multipart e-mail add the mime_version if it is not
# already set.
@ -556,6 +493,7 @@ module ActionMailer #:nodoc:
end
private
# Set up the default values for the various instance variables of this
# mailer. Subclasses may override this method to provide different
# defaults.
@ -568,38 +506,42 @@ module ActionMailer #:nodoc:
@mailer_name ||= self.class.name.underscore
@parts ||= []
@headers ||= {}
@body ||= {}
@mime_version = @@default_mime_version.dup if @@default_mime_version
@sent_on ||= Time.now
super # Run deprecation hooks
end
def render(*args)
# TODO Fix me. Deprecate assigns to be given as a :body hash
options = args.last.is_a?(Hash) ? args.last : {}
if options[:body]
options.delete(:body).each do |k, v|
instance_variable_set(:"@#{k}", v)
def create_parts
super # Run deprecation hooks
if String === response_body
@parts.unshift Part.new(
:content_type => "text/plain",
:disposition => "inline",
:charset => charset,
:body => response_body
)
else
self.class.template_root.find_all(@template, {}, mailer_name).each do |template|
@parts << Part.new(
:content_type => template.mime_type ? template.mime_type.to_s : "text/plain",
:disposition => "inline",
:charset => charset,
:body => render_to_body(:_template => template)
)
end
if @parts.size > 1
@content_type = "multipart/alternative" if @content_type !~ /^multipart/
@parts = sort_parts(@parts, @implicit_parts_order)
end
end
super
end
def template_root
self.class.template_root
end
def template_root=(root)
self.class.template_root = root
end
def template_path
"#{mailer_name}"
end
def sort_parts(parts, order = [])
order = order.collect { |s| s.downcase }
parts = parts.sort do |a, b|
a_ct = a.content_type.downcase
b_ct = b.content_type.downcase
@ -648,14 +590,6 @@ module ActionMailer #:nodoc:
m.set_content_type(real_content_type, nil, ctype_attrs)
m.body = normalize_new_lines(@parts.first.body)
else
if String === body
part = TMail::Mail.new
part.body = normalize_new_lines(body)
part.set_content_type(real_content_type, nil, ctype_attrs)
part.set_content_disposition "inline"
m.parts << part
end
@parts.each do |p|
part = (TMail::Mail === p ? p : p.to_mail(self))
m.parts << part

View file

@ -0,0 +1,44 @@
module ActionMailer
# TODO Remove this module all together in a next release. Ensure that super
# hooks in ActionMailer::Base are removed as well.
module DeprecatedBody
def self.included(base)
base.class_eval do
# Define the body of the message. This is either a Hash (in which case it
# specifies the variables to pass to the template when it is rendered),
# or a string, in which case it specifies the actual text of the message.
adv_attr_accessor :body
end
end
def initialize_defaults(method_name)
@body ||= {}
end
def create_parts
if String === @body
ActiveSupport::Deprecation.warn('body is deprecated. To set the body with a text ' <<
'call render(:text => "body").', caller[7,1])
self.response_body = @body
elsif @body.is_a?(Hash) && !@body.empty?
ActiveSupport::Deprecation.warn('body is deprecated. To set assigns simply ' <<
'use instance variables', caller[7,1])
@body.each { |k, v| instance_variable_set(:"@#{k}", v) }
end
end
def render(*args)
options = args.last.is_a?(Hash) ? args.last : {}
if options[:body]
ActiveSupport::Deprecation.warn(':body is deprecated. To set assigns simply ' <<
'use instance variables', caller[0,1])
options.delete(:body).each do |k, v|
instance_variable_set(:"@#{k}", v)
end
end
super
end
end
end

View file

@ -1,6 +1,5 @@
# encoding: utf-8
require 'abstract_unit'
require 'active_support/testing/pending'
class FunkyPathMailer < ActionMailer::Base
self.template_root = "#{File.dirname(__FILE__)}/fixtures/path.with.dots"
@ -291,7 +290,6 @@ end
class ActionMailerTest < Test::Unit::TestCase
include ActionMailer::Quoting
include ActiveSupport::Testing::Pending
def encode( text, charset="utf-8" )
quoted_printable( text, charset )
@ -979,10 +977,8 @@ EOF
end
def test_body_is_stored_as_an_ivar
pending "needs attr_internal on @body" do
mail = TestMailer.create_body_ivar(@recipient)
assert_equal "body: foo\nbar: baz", mail.body
end
mail = TestMailer.create_body_ivar(@recipient)
assert_equal "body: foo\nbar: baz", mail.body
end
def test_starttls_is_enabled_if_supported