- Read Tutorial
- Watch Guide Video
In this guide we are going to implement our final feature for this version of the application which is the ability for our proposals to be emailed out to clients. So right here we have action Mailer and you can go to the rubyonrails.org
site and it has the full guide on how you can go generate a mailer. I don't exactly create a new mailer every single day so I don't always have every one of the steps memorized and I make sure to always go and look at the documentation to make sure I'm not missing something. So the very first command we're going to run in the terminal is going to be rails generate mailer
and then whatever the name of the mailer is so ours is going to be a ProposalMailer.
So the very first thing we're going to want to do is type in
rails g mailer ProposalMailer
And this is going to generate the necessary files for the mailer to work. And now what we can do is open up our application_mailer.rb
and set this up so I'm going to open up Sublime and bring up the code right here. So this created an application_mailer.rb
and this is where we can set the default from. So we'll just say that this is from the mailerbot@devcamp.com
. layout 'mailer'
everything there can stay the same. And then we can also look and see that we have a proposal_mailer.rb
file right here and this is where we can put all the logic for the actual mail component. Inside of proposal_mailer.rb
we don't need to change the default from because the default from is inherited from ApplicationMailer
and we don't need to override that and I'm going to call this method def email()
.
And inside of it we're going to pass in a client
or should it be proposal
? Let me think about it for a second we're going to e-mail a client but we need to get that from a proposal so it makes more sense to actually call the argument proposal
and here I'm going to call @proposal
and set this equal to proposal
. And then we have to create our actual mail()
call. So this is going to call a mail()
method which is something that is available to us because we are inheriting from ApplicationMailer
and the first argument is going to be to:
we're going to say that we want to mail this to the @proposal.client_email
and we can look up our schema.rb
file to make sure it is client_email
. Just to make sure our attributes are correct. So that is going to mail to the client and then from there we need to pass in a subject:
the subject is going to be "You've received a new proposal"
and that is all we have to do inside of this method.
def email(proposal) @proposal = proposal mail(to: @proposal.client_email, subject: "You've received a new proposal") end
and inside of the app/views/proposal_mailer
directory but no files our inside of it so we need to create a new file inside of it and this is going to be called email because it has to be the same name as our method. So it's going to be email.text.erb
and inside of this, we're going to access all of the items and show whatever needs to be shown on the screen. So thankfully this isn't too difficult because we have access to the entire mail data. So here we can use some erb and paste in <%= @proposal.customer %>
. Then here we are going to start off by saying Hello <%= @proposal.customer %>
and then I'm going to just add a line because we're doing a straight e-mail text so we don't have access to do things like horizontal lines or anything like that because we're not using HTML now here we can say that You have received a new proposal, to view it click the link below:
and eventually if we integrate authentication, then we could also pass in who the freelancer is who is sending this, but for right now we can just say this. So in this case what we want to do is actually grab our link, for our local site it's going to be http://localhost:3000/proposal/<%= @proposal.id %>
and so this is going to be because if you go and look at this say that it's a proposal of ID 5 then remember the way our route works inside of our application inside of our front-end application it is going to be directed right here so all of this should work. I can't think of anything else we have to do on that side.
Hello <%= @proposal.customer %>, ================================== You have received a new proposal, to view it click the link below: http://localhost:3000/proposal/<%= @proposal.id %>
So the next thing we need to do is actually call this because obviously this doesn't do anything unless you call it. So let's go inside of our controller. So I'm going to go to our proposals_controller.rb
and inside of this def create
we don't want it to be sent out before this has been validated. So we want to inside of the def create
we'll say our ProposalMailer.email
and then pass in the(@proposal)
just like that and then we'll do .deliver_later
and that's going to deliver the item for us. Now we have to make a couple final changes on the email side and if you scroll down they give you some of the configuration options in order to make this truly work we would have to actually configure an e-mail server and I'm not going to set an e-mail server for that we've done that in previous Rails courses and there are a million tutorials to do that so that's not too challenging to do.
But one thing we will add is the ability to actually have the configuration options so I at least want to show you where you can put those. So scrolling down there's all kinds of different things in the documentation for how you can do this or not just this but how all the things you can do with Action Maler. Let's see this is Action Mailer Configuration and here it is so we have example Action Mailer Configuration this is going to show you how to use (this one is using sendmail
). But you can also use G-mail or you can use any kind of setup you want and that's what's going to be required if you actually want to send the e-mail. You also can just go in and if you go to your development.rb
file and this is located in config/environment/development.rb
then you could go here and you'll also have to add in some of the configuration options here we're not going to set up the email server so it's fine all I'm going to care about is looking inside the terminal because that's going to show if the email gets sent or not. But just so you are aware in order to make this work you have to update your environment both your development and production one with the e-mail configuration options. Then you're going to have to create an initializer like they do right here in the documentation for setting up mail and you can connect it to any email service you want. I usually use Spark Post nowadays. And then you'll be able to send emails.
But in the meantime let's actually try this out and see if this works so I'm going to come over to our actual system and say
rails s -p 3002
So we're going startup the rails server this is going to load the rails environment to make sure we don't have any bugs or any syntax errors in the code and it looks like we are all good to go on that side we can even come to Rails 3002, hit refresh and see all of that's working on the site. If I come to proposals you can see that all of this is working because all this is coming in from the API and notice how the data is being called every two seconds this data is being called so it's updated inside of our proposals and now let's check our email function. I'm going to type Oracle as a customer and for the portfolio ID, it's going to be `portfolio. jordanhudgens.com. Tools that we're going to use is we're going to use Oracle database of course estimated hours 90, hourly rate 150, weeks to complete 90 ,and the client email, in this case, will be jordan@devcamp.com. Now if I generate this proposal we should see the email we'll also get an error because we don't have an e-mail server setup but it will show the email that got generated so all we have to do is click generate proposal. And after that is pressed Let's come into the logs and see what else has happened. So here we have a few things that occurred and looks like we had an error. So we have a completed with a 500 internal server error and it's a name error uninitialized constant proposals controller proposals mailer. So let's see exactly what is going on with that.
So it looks like this is the issue (Jordan is in the proposal_controller.rb
file and is referring to ProposalsMailer
on line 21) and I need to come in here and it's because I called it ProposalsMailer
(plural) instead of ProposalMailer
(singular) so that should do the trick. Now let's come back and you can see that still created the record. It just didn't send the email. So everything on that side still worked which is why we didn't get an error message or anything breaking here.
So now let's try another one. This one is going to be AOL and I have no idea we'll pretend AOL uses C for their tools. Estimated hours 80, hourly rate was 20 weeks to complete 30, and client e-mail is going to be jordan@aol.com. I don't have that address but it would be cool if I did. Now if I click generate proposal. And this is going to send the API request. And now if I scroll down and look at this hopefully we'll see an e-mail. So I'm going to scroll through all of those and look at that right here.
This is the e-mail you can see. So we have this message with a message ID. It was sent to jordan@aol.com from mailerbot@devcamp.com. So all of this is set up properly. And it says Hello AOL you have received a new proposal to view it click on the link below:
and then we have this link. Now if we say that we did come in to the browser and clicked it. This is going to take the customer right to their proposal. So this is working perfectly. Great job if you finished that you now have a fully set up angular front end application are going to follow up in the next guide and just do a review of everything that we implemented. So great job with everything.