Forum: Ruby on Rails Sending mail templates to a mailinglist

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-01 11:54
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
-----------------------------------------------------------------------

<h1>Send Email</h1>

<% form_tag :action => "sendmail" do %>
    <p>
        <label for="email_subject">Subject</label>:
        <%= text_field 'email', 'subject' %>
    </p>
    <p>
        <label for="email_recipient">Recipient</label>:
        <%= text_field 'email', 'recipient' %>
    </p>
    <p>
        <label for="email_message">Message</label><br/>
        <%= text_area 'email', 'message' %>
    </p>
        <%= submit_tag "sendmail" %>
<% end %>
-------------------------------------------------------------------------

mailinglists show.html.erb - using the mail_template
-------------------------------------------------------------------------
<b>Mail Template(s) in use:</b>
<% 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 %>
</p>
<br/>
<hr> <h4><b>Subscriber List</b></h4>
<% for mailing in @mailinglist_mailings %>
    <p><%= mailing.email_address %></p>
<% 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 = 'mailinglists@service-app.uk.org'
      @sent_on = sent_at
      @content_type = "text/html"
      @body["title"] = 'This is title'
        @body["email"] = 'mailinglists@service-app.uk.org'
         @body["message"] = message
      @headers = {}
   end
end
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-01 15:54
(Received via mailing list)
On 1 Dec 2008, at 10:54, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-01 17:58
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 Cheung wrote:
> On 1 Dec 2008, at 10:54, Dave Smith 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
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-01 18:10
(Received via mailing list)
On 1 Dec 2008, at 16:58, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-01 18:22
Frederick Cheung wrote:
> On 1 Dec 2008, at 16:58, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-02 11:48
Dave Smith wrote:
> Frederick Cheung wrote:
>> On 1 Dec 2008, at 16:58, Dave Smith 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.
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-02 12:00
(Received via mailing list)
On 2 Dec 2008, at 10:48, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-02 12:27
Frederick Cheung wrote:
> On 2 Dec 2008, at 10:48, Dave Smith 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
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-02 13:23
(Received via mailing list)
On 2 Dec 2008, at 11:27, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-02 14:26
Frederick Cheung wrote:
> On 2 Dec 2008, at 11:27, Dave Smith 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 Smith     smith@yahoo.com

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
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-02 14:35
(Received via mailing list)
On 2 Dec 2008, at 13:26, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-02 15:25
Frederick Cheung wrote:
> On 2 Dec 2008, at 13:26, Dave Smith 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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-03 14:07
Frederick Cheung wrote:
> On 2 Dec 2008, at 13:26, Dave Smith 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!!
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-03 14:12
(Received via mailing list)
On Dec 3, 1:07 pm, Dave Smith <rails-mailing-l...@andreas-s.net>
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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-03 14:27
Frederick Cheung wrote:
> On Dec 3, 1:07�pm, Dave Smith <rails-mailing-l...@andreas-s.net>
> 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
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-03 14:45
(Received via mailing list)
On Dec 3, 1:27 pm, Dave Smith <rails-mailing-l...@andreas-s.net>
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
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-03 14:59
Frederick Cheung wrote:
> On Dec 3, 1:27�pm, Dave Smith <rails-mailing-l...@andreas-s.net>
> 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:in
`const_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:in
`const_missing'
app/controllers/admin/mailinglists_controller.rb:116:in `send_mail'
app/controllers/admin/mailinglists_controller.rb:115:in `send_mail'
app/controllers/admin/mailinglists_controller.rb:114:in `send_mail'
Request

Parameters:

{"authenticity_token"=>"dc9249eaed248ed10c939b4b0fd52c0c373c5f09",
 "id"=>"1"}
Show session dump
428f1d76da99d9602d57b046841df29a?d=identicon&s=25 Dave Smith (railsnoob)
on 2008-12-03 15:03
> 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:in
> `const_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:in
> `const_missing'
> app/controllers/admin/mailinglists_controller.rb:116:in `send_mail'
> app/controllers/admin/mailinglists_controller.rb:115:in `send_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?
81b61875e41eaa58887543635d556fca?d=identicon&s=25 Frederick Cheung (Guest)
on 2008-12-03 15:09
(Received via mailing list)
On Dec 3, 2:03 pm, Dave Smith <rails-mailing-l...@andreas-s.net>
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
This topic is locked and can not be replied to.