Sending mail templates to a mailinglist


#1

As a noob to rails I am struggling with being able to send a mail
template (html) stored in my database to all the users on a mailing
list. I can use the emailer page to send the mail template to a single
email address, but I want to be able to put a button on the mailinglists
show page that sends the mail template to all the mailings in the
mailinglist. The code is below for the key sections I am using.

I have been trying to figure out a solution for 4 days now and still
cannot get anything working and am loosing the will to live!!

Please if anyone could help me on this one I would be very very
greatfull.

Regards,

David

emailer controller

class Admin::EmailerController < Admin::AdminController
def sendmail
email = params[:email]
recipient = email[“recipient”]
subject = email[“subject”]
message = email[“message”]
Emailer.deliver_contact(recipient, subject, message)
return if request.xhr?
render :text => ‘Message sent successfully’
end

#def index
# render :file => ‘app\views\admin\emailer\index.html.erb’
#end

end


emailer index.html.erb

Send Email

<% form_tag :action => “sendmail” do %>


Subject:
<%= text_field ‘email’, ‘subject’ %>



Recipient:
<%= text_field ‘email’, ‘recipient’ %>



Message

<%= text_area ‘email’, ‘message’ %>


<%= submit_tag “sendmail” %>
<% end %>

mailinglists show.html.erb - using the mail_template

Mail Template(s) in use:
<% for mail_template in @mailinglist_templates %>
<%= link_to “#{mail_template.name}”,
admin_mail_template_path(mail_template), :class => ‘websnapr’ %>
<%= link_to ‘Edit’, edit_admin_mail_template_path(mail_template) %>

<% end %>



Subscriber List

<% for mailing in @mailinglist_mailings %>

<%= mailing.email_address %>

<% end %>

oh and here is my mailer model


class Admin::Emailer < ActionMailer::Base
def contact(recipient, subject, message, sent_at = Time.now)
@subject = subject
@recipients = recipient
@from = ‘removed_email_address@domain.invalid’
@sent_on = sent_at
@content_type = “text/html”
@body[“title”] = ‘This is title’
@body[“email”] = ‘removed_email_address@domain.invalid’
@body[“message”] = message
@headers = {}
end
end


#2

On 1 Dec 2008, at 10:54, Dave S. wrote:

As a noob to rails I am struggling with being able to send a mail
template (html) stored in my database to all the users on a mailing
list. I can use the emailer page to send the mail template to a single
email address, but I want to be able to put a button on the
mailinglists
show page that sends the mail template to all the mailings in the
mailinglist. The code is below for the key sections I am using.

Well instead of doing

Emailer.deliver_contact(recipient, subject, message)

You could clearly do

recipients.each do |recipient|
Emailer.deliver_contact(recipient, subject, message)
end

assuming that recipients was some collection of email addresses

Fred


#3

Hi Fred,

At present the recipient is a single email address coming from the
emailer page (just to test the mailer works).

I have moved the sendmail form into the mailinglists index view page
(and also moved the sendmail function from the emailer controller to the
mailinglist controller) and it still works fine by sending the
recipient, subject, message to the emailer model.

However I created a mailings scaffold which holds each of the email
addresses, and names for the people on the mailinglist (with a one to
many relationship).

So now I am stuck as I dont know how to create a button that sends an
email to all the mailings in a mailinglist with the mailinglist_template
associated with that mailinglist!!

Any help on this would be greatly appreciated!!

Kindest Regards,

Louis

Frederick C. wrote:

On 1 Dec 2008, at 10:54, Dave S. wrote:

As a noob to rails I am struggling with being able to send a mail
template (html) stored in my database to all the users on a mailing
list. I can use the emailer page to send the mail template to a single
email address, but I want to be able to put a button on the
mailinglists
show page that sends the mail template to all the mailings in the
mailinglist. The code is below for the key sections I am using.

Well instead of doing

Emailer.deliver_contact(recipient, subject, message)

You could clearly do

recipients.each do |recipient|
Emailer.deliver_contact(recipient, subject, message)
end

assuming that recipients was some collection of email addresses

Fred


#4

Frederick C. wrote:

On 1 Dec 2008, at 16:58, Dave S. wrote:

recipient, subject, message to the emailer model.

However I created a mailings scaffold which holds each of the email
addresses, and names for the people on the mailinglist (with a one to
many relationship).

So now I am stuck as I dont know how to create a button that sends an
email to all the mailings in a mailinglist with the
mailinglist_template
associated with that mailinglist!!

Doesn’t that just mean that recipients = mailinglist.people.collect {|
person| person.email_address}
?
Fred

yeah well in my mailinglist controller I have put

@mailinglist_mailings = @mailinglist.mailings.collect

so essentially very similar


#5

On 1 Dec 2008, at 16:58, Dave S. wrote:

recipient, subject, message to the emailer model.

However I created a mailings scaffold which holds each of the email
addresses, and names for the people on the mailinglist (with a one to
many relationship).

So now I am stuck as I dont know how to create a button that sends an
email to all the mailings in a mailinglist with the
mailinglist_template
associated with that mailinglist!!

Doesn’t that just mean that recipients = mailinglist.people.collect {|
person| person.email_address}
?
Fred


#6

Dave S. wrote:

Frederick C. wrote:

On 1 Dec 2008, at 16:58, Dave S. wrote:

recipient, subject, message to the emailer model.

However I created a mailings scaffold which holds each of the email
addresses, and names for the people on the mailinglist (with a one to
many relationship).

So now I am stuck as I dont know how to create a button that sends an
email to all the mailings in a mailinglist with the
mailinglist_template
associated with that mailinglist!!

Doesn’t that just mean that recipients = mailinglist.people.collect {|
person| person.email_address}
?
Fred

yeah well in my mailinglist controller I have put

@mailinglist_mailings = @mailinglist.mailings.collect

so essentially very similar

so does that mean I put an AJAX button in my view page to run the “do”
code, or does the code have to be placed in the emailer model?

Sorry for my lack of knowledge as ive only been using rails for a couple
of weeks and am learning it by myself.


#7

Frederick C. wrote:

On 2 Dec 2008, at 10:48, Dave S. wrote:

many relationship).
?
Fred

yeah well in my mailinglist controller I have put

@mailinglist_mailings = @mailinglist.mailings.collect

so essentially very similar

so does that mean I put an AJAX button in my view page to run the “do”
code, or does the code have to be placed in the emailer model?

whether this happens in the controller or in the emailer this mostly
depends if you want 1 email sent to everyone, or to send however many
separate emails (with identical content).
I think AJAX is an orthogonal issue - you could have a regular button
or an ajax one and it wouldn’t change much.

Fred

to be honest i dont really care how the emails are sent. which ever
method is easiest to impliment. Do you know of any examples that are
similar as I dont really know where to start on this one.

Kindest Regards,

Dave


#8

On 2 Dec 2008, at 10:48, Dave S. wrote:

many relationship).
?
Fred

yeah well in my mailinglist controller I have put

@mailinglist_mailings = @mailinglist.mailings.collect

so essentially very similar

so does that mean I put an AJAX button in my view page to run the “do”
code, or does the code have to be placed in the emailer model?

whether this happens in the controller or in the emailer this mostly
depends if you want 1 email sent to everyone, or to send however many
separate emails (with identical content).
I think AJAX is an orthogonal issue - you could have a regular button
or an ajax one and it wouldn’t change much.

Fred


#9

On 2 Dec 2008, at 11:27, Dave S. wrote:

@mailinglist_mailings = @mailinglist.mailings.collect
I think AJAX is an orthogonal issue - you could have a regular button
or an ajax one and it wouldn’t change much.

Fred

to be honest i dont really care how the emails are sent. which ever
method is easiest to impliment. Do you know of any examples that are
similar as I dont really know where to start on this one.

I’m sort of struggling to see what the problem is to be honest.

if in your view you had

button_to :send_mail, :id => some_template.id, :mailing_list_id =>
some_mailing_list_id

then your controller could be as simple as

def send_mail
@mail_template = MailTemplate.find params[:id]
@mailing_list = MailingList.find params[:mailing_list_id]
@mailing_list.people.each do |person|
Emailer.deliver_message person.email_address,
@mail_template.subject, @mail_template.body
end
end

(I’m assuming a bunch of things about which attributes and
associations your models have but it should be quite obvious)

Fred


#10

Frederick C. wrote:

On 2 Dec 2008, at 11:27, Dave S. wrote:

@mailinglist_mailings = @mailinglist.mailings.collect
I think AJAX is an orthogonal issue - you could have a regular button
or an ajax one and it wouldn’t change much.

Fred

to be honest i dont really care how the emails are sent. which ever
method is easiest to impliment. Do you know of any examples that are
similar as I dont really know where to start on this one.

I’m sort of struggling to see what the problem is to be honest.

if in your view you had

button_to :send_mail, :id => some_template.id, :mailing_list_id =>
some_mailing_list_id

then your controller could be as simple as

def send_mail
@mail_template = MailTemplate.find params[:id]
@mailing_list = MailingList.find params[:mailing_list_id]
@mailing_list.people.each do |person|
Emailer.deliver_message person.email_address,
@mail_template.subject, @mail_template.body
end
end

(I’m assuming a bunch of things about which attributes and
associations your models have but it should be quite obvious)

Fred

Thank you Fred,

It gets a little more complicated because the mailinglist has many
mailings (database table shown below).

id mailinglist_id name email_address
1 2 Dave S. removed_email_address@domain.invalid

So I thought you would have to collect these first then loop through
them…

somthing like the following perhaps?

def send_mail
@mail_template = MailTemplate.find(params[:id])
@mailing_list = MailingList.find(params[:mailing_list_id])
@mailinglist_mailings = @mailinglist.mailings.collect
--------- @mailinglist_mailings.mailing.each do |mailing|
Emailer.deliver_contact(mailing.email_address,
@mail_template.subject, @mail_template.body)
end
return if request.xhr?
render :text => ‘Message sent successfully’
end

but i dont think that the line @mailinglist_mailings.mailing.each do
|mailing| is right


#11

Frederick C. wrote:

On 2 Dec 2008, at 13:26, Dave S. wrote:

Fred
button_to :send_mail, :id => some_template.id, :mailing_list_id =>
end
mailings (database table shown below).
@mail_template = MailTemplate.find(params[:id])
@mailing_list = MailingList.find(params[:mailing_list_id])

@mailinglist_mailings = @mailinglist.mailings.collect

This line above is pointless. collect with no block passed just
returns the original array.
THe point of collect/map is to create a new collection by applying a
function to each element (eg given an array of numbers construct an
array with the square of each number: numbers.collect {|n| n*n} )

@mailing_list.mailings.each do |mailing|
Emailer.deliver_contact(mailing.email_address,
@mail_template.subject, @mail_template.body)
end

Fred

yep brilliant, a few tweaks here and there and ive got it running. Thank
you very much for your help!

Kindest Regrds


#12

On 2 Dec 2008, at 13:26, Dave S. wrote:

Fred
button_to :send_mail, :id => some_template.id, :mailing_list_id =>
end
mailings (database table shown below).
@mail_template = MailTemplate.find(params[:id])
@mailing_list = MailingList.find(params[:mailing_list_id])

@mailinglist_mailings = @mailinglist.mailings.collect

This line above is pointless. collect with no block passed just
returns the original array.
THe point of collect/map is to create a new collection by applying a
function to each element (eg given an array of numbers construct an
array with the square of each number: numbers.collect {|n| n*n} )

@mailing_list.mailings.each do |mailing|
Emailer.deliver_contact(mailing.email_address,
@mail_template.subject, @mail_template.body)
end

Fred


#13

Frederick C. wrote:

On 2 Dec 2008, at 13:26, Dave S. wrote:

Fred
button_to :send_mail, :id => some_template.id, :mailing_list_id =>
end
mailings (database table shown below).
@mail_template = MailTemplate.find(params[:id])
@mailing_list = MailingList.find(params[:mailing_list_id])

@mailinglist_mailings = @mailinglist.mailings.collect

This line above is pointless. collect with no block passed just
returns the original array.
THe point of collect/map is to create a new collection by applying a
function to each element (eg given an array of numbers construct an
array with the square of each number: numbers.collect {|n| n*n} )

@mailing_list.mailings.each do |mailing|
Emailer.deliver_contact(mailing.email_address,
@mail_template.subject, @mail_template.body)
end

Fred

one final question… i have the code working, and can send a mail
template to a list of mailings… but in order to send more than one
mailtemplate to these users i have had to create a button for each
template as shown below…

<% for mail_template in @mailinglist_templates %>
<%= button_to “sendmail”, { :action => “send_mail”, :mail_template_id =>
mail_template.id, :id => params[:id] } %>
<% end %>

now this i know is poor programming and looks bad too… is there a way i
can just have one button that sends each of the mail templates to all
the users in the list…?

again many thanks for your help!!


#14

Frederick C. wrote:

On Dec 3, 1:07�pm, Dave S. removed_email_address@domain.invalid
wrote:

now this i know is poor programming and looks bad too… is there a way i
can just have one button that sends each of the mail templates to all
the users in the list…?

just call the action something like send_all_mails or something like
that and drop the :mail_template_id parameter and do that iteration
over all templates in the controller.

If you wanted to get a bit more fancy then you could have a checkbox
for each template you want to send (whether you have a list of
templates with a checkbox for each mailing list that should receive it
or a list of mailing list with checkboxes for each template that
should go to a given mailing list is down to what makes the most
business sense to you)

Fred

I presume somthing similar to this would work

@mailing_list = Mailinglist.find(params[:id])
@mail_templates = @mailing_list.mail_templates.collect

@mail_templates.mail_templates.each do |mail_template|
  @mailing_list.mailings.each do |mailing|
    Emailer.deliver_contact(mailing.email_address, 

@mail_template.name, @mail_template.content)
end
end


#15

On Dec 3, 1:27 pm, Dave S. removed_email_address@domain.invalid
wrote:

over all templates in the controller.
I presume somthing similar to this would work

@mailing_list = Mailinglist.find(params[:id])
@mail_templates = @mailing_list.mail_templates.collect

collect with no block does nothing

@mail_templates.mail_templates.each do |mail_template|

Just @mailing_list.mail_templates.each
will do here, assuming mailing_list has_many mail_templates

Fred


#16

On Dec 3, 1:07 pm, Dave S. removed_email_address@domain.invalid
wrote:

now this i know is poor programming and looks bad too… is there a way i
can just have one button that sends each of the mail templates to all
the users in the list…?

just call the action something like send_all_mails or something like
that and drop the :mail_template_id parameter and do that iteration
over all templates in the controller.

If you wanted to get a bit more fancy then you could have a checkbox
for each template you want to send (whether you have a list of
templates with a checkbox for each mailing list that should receive it
or a list of mailing list with checkboxes for each template that
should go to a given mailing list is down to what makes the most
business sense to you)

Fred


#17

Application Trace | Framework Trace | Full Trace
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:253:in
load_missing_constant' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:468:inconst_missing’
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:486:in
send' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:486:inconst_missing’
app/controllers/admin/mailinglists_controller.rb:116:in send_mail' app/controllers/admin/mailinglists_controller.rb:115:insend_mail’
app/controllers/admin/mailinglists_controller.rb:114:in `send_mail’
Request

Parameters:

{“authenticity_token”=>“dc9249eaed248ed10c939b4b0fd52c0c373c5f09”,
“id”=>“1”}
Show session dump

dont worry, i fixed it by prepending Admin:: to the reference of the
model… but out of curiosity, why did it work the first time and not the
second time?


#18

On Dec 3, 2:03 pm, Dave S. removed_email_address@domain.invalid
wrote:

Application Trace | Framework Trace | Full Trace

dont worry, i fixed it by prepending Admin:: to the reference of the
model… but out of curiosity, why did it work the first time and not the
second time?

Probably some weird dependencies thing. Hard to say more from here.

Fred


#19

Frederick C. wrote:

On Dec 3, 1:27�pm, Dave S. removed_email_address@domain.invalid
wrote:

over all templates in the controller.
I presume somthing similar to this would work

�@mailing_list = Mailinglist.find(params[:id])
� � @mail_templates = @mailing_list.mail_templates.collect

collect with no block does nothing

� � @mail_templates.mail_templates.each do |mail_template|

Just @mailing_list.mail_templates.each
will do here, assuming mailing_list has_many mail_templates

Fred

brilliant, thank you Fred. I have the code working without syntax
errors. There is however a problem where it will only work once in both
loops. for example if i have more than one email address in the
mailinglist, or more than one template it sends the first email to me no
problem but then throws the following error

ArgumentError in Admin/mailinglistsController#send_mail

Admin is not missing constant Emailer!
RAILS_ROOT: C:/ruby/myprojects/service

Application Trace | Framework Trace | Full Trace
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:253:in
load_missing_constant' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:468:inconst_missing’
c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:486:in
send' c:/ruby/lib/ruby/gems/1.8/gems/activesupport-2.1.1/lib/active_support/dependencies.rb:486:inconst_missing’
app/controllers/admin/mailinglists_controller.rb:116:in send_mail' app/controllers/admin/mailinglists_controller.rb:115:insend_mail’
app/controllers/admin/mailinglists_controller.rb:114:in `send_mail’
Request

Parameters:

{“authenticity_token”=>“dc9249eaed248ed10c939b4b0fd52c0c373c5f09”,
“id”=>“1”}
Show session dump