Sending Mail with Rails

Problem

You want to send an email from within your Rails application: perhaps a confirmation of an order, or notification that some action has been taken on a users behalf.

Solution

The first is to generate some mailer infrastructure. Go to the applications base directory and type this command:

	./script/generate mailer Notification welcome
	 exists app/models/
	 create app/views/notification
	 exists test/unit/
	 create test/fixtures/notification
	 create app/models/notification.rb
	 create test/unit/notification_test.rb
	 create app/views/notification/welcome.rhtml
	 create test/fixtures/notification/welcome

We e giving the name "Notification" to the mailing center of the application; its somewhat analogous to a controller in the web interface. The mailer is set up to generate a single email, called "welcome": this is analagous to an action with a view template.

Now open app/models/notification.rb and edit it to look like this:

	class Notification < ActionMailer::Base
	 def welcome(user, sent_at=Time.now)
	 @subject = A Friendly Welcome
	 @recipients = user.email
	 @from = admin@mysite.com
	 @sent_on = sent_at
	 @body = {
	 :user => user,
	 :sent_on => sent_at
	 }
	 attachment 	ext/plain do |a|
	 a.body = File.read(
ules.txt)
	 end
	 end
	end

The subject of the email is "A Friendly Welcome", and its sent to the users email address from the address "admin@mysite.com". Its got an attachment taken from the disk file rules.txt (relative to the root directory of your Rails application).

Although the file notification.rb is within the models/ directory, it acts like a controller in that each of its email messages has an associated view template. The view for the welcome email is in app/views/notification/welcome.rhtml, and it acts almost the same as the view of a normal controller.

The most important difference is that mailer views do not have access to the instance variables of the mailer. To set instance variables for mailers, you pass a hash of those variables to the body method. The keys become instance variable names and the values become their values. In notification.rb, we make two instance variables available to the welcome view, @user and @sent_on. Heres the view itself:

	

	Hello, <%= @user.name %>, and thanks for signing up at <%= @sent_on
	%>. Please print out the attached set of rules and keep them in a
	prominent place; they help keep our community running smoothly. Be
	sure to pay special attention to sections II.4 ("Assignment of
	Intellectual Property Rights") and XIV.21.a ("Dispute Resolution
	Through Ritual Combat").

To send the welcome email from your Rails application, add the following code to either a controller, a model, or an observer:

	Notification.deliver_welcome(user) 

Here, the user variable can be any object that implements #name and #email, the two methods called in the welcome method and in the template.

Discussion

You never call the Notification#welcome method directly. In fact, Notification#welcome is not even available, since its an instance method, and you never instantiate a Notification object directly. The ActionMailer::Base class defines a method_missing implementation that looks at all calls to undefined class methods. This is why you call deliver_welcome even though you never defined it.

The welcome.rhtml template given above generates plaintext email. To send HTML emails, simply add the following code to Notification#welcome:

	content_type 	ext/html

Now your templates can generate HTML; email clients will recognize the format of the email and render it appropriately.

Sometimes youll want more control over the delivery processfor example, when you e unit-testing your ActionMailer classes. Instead of calling deliver_welcome to send out an email, you can call create_welcome to get the email as a Ruby object. These "create" methods return TMail objects, which you can examine or manipulate as necessary.

If your local web server is incapable of sending email, you can modify environment.rb to contact a remote SMTP server:

	 
Rails::Initializer.run do |config|
	 config.action_mailer.server_settings = {
	 :address => someserver.com,
	 : 
user_name => uname,
	 :password => passwd,
	 :authentication => cram_md5
	 }
	end

See Also

  • Recipe 10.8, "Responding to Calls to Undefined Methods"
  • Recipe 14.5, "Sending Mail," has more on ActionMailer and SMTP settings


Strings

Numbers

Date and Time

Arrays

Hashes

Files and Directories

Code Blocks and Iteration

Objects and Classes8

Modules and Namespaces

Reflection and Metaprogramming

XML and HTML

Graphics and Other File Formats

Databases and Persistence

Internet Services

Web Development Ruby on Rails

Web Services and Distributed Programming

Testing, Debugging, Optimizing, and Documenting

Packaging and Distributing Software

Automating Tasks with Rake

Multitasking and Multithreading

User Interface

Extending Ruby with Other Languages

System Administration



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net