Reputation: 13929
Gems like mail_view, mailcatcher, rails_email_preview, etc. seem to be more developer-oriented (a way to debug a template). But I need something that will be used by the trusted users of my rails app in production.
My app is a project management app, where project managers can update the status of their projects, operations during which emails must be sent to project contractors, developers, clients, etc.
The project manager must be able to tell whether or not he wants to send an email (this is easy), and be able to customize to some extent the message content (not the design, only specific text parts should be enough). They DO want to have some control over the email about to be sent, ie, they need a preview of the email they customized. Why ?
<h2>
just because they forgot a closing </h2>
Hello M. President,
)<h2>
, etc. So I need to render the email with the CSSProject managers have access to a form that will feed the content to my Rails app. I am thinking on having both a normal submit button, and a previsualize button. I will probably use some tricks given by this SO question to differentiate the behaviours of the 2 buttons
I am using letter_opener for debug (so different context), but this is typically the preview I'd like to show to the project manager. However, in order to be used, letter_opener requires to modify action_mailer configuration config.action_mailer.delivery_method = :sendmail # (or :letter_opener)
. So I can only previews emails, or send them for real, not both ? I would accept a solution that would let me choose whether to use letter_opener or send the email for real
Instead of blindly trusting my project managers' ability to write basic html without forgetting closing tag, maybe you could recommend a nice WYSIWYG editor that would show the content of my f.text_area()
?
This would be a bonus, not an actual answer to my question
I am now aware that different email clients can render the email client differently. I will ignore this for now. So the way the preview is rendered doesn't matter. I like the rendering of letter_opener
however
View > Controller > Mailer
my_email_view.html.erb
<%= form_tag some_mailing_list_path %>
<%= fields_for :email do |f| %>
<!-- f.text_field(:subject, ....), etc -->
<% end %>
<%= submit_tag("Send email") %>
<%= submit_tag("Preview") %>
<% end %>
my_controller.rb
before_action :prep_email # Strong parameters, define @mail with form contents
# Handles the POST
def some_action
check(:to, :from, :subject) # I check the parameters in private functions
if email_alright? # Above checks will raise a flag if something went wrong
if Rails.env.production?
MailingListsMailer.my_action(@mail).deliver_later
else
MailingListsMailer.my_action(@mail).deliver_now
end
flash.notice = "Email sent"
redirect_to :back
else
redirect_to :back
end
end
mailing_list_mailer.rb
def my_action(message)
format_mail_params(message) # Will set more variables
@etude = etude
@include_reference = message[:include_reference]
@include_description = message[:include_description]
dst = Proc.new { read_emails_file }
mail(
to: dst,
from: message[:from],
subject: @subject_full)
end
Upvotes: 1
Views: 855
Reputation: 1761
Question update: based on your pseudocode, this is a simple case of creating a status update model and emailing the update to a mailing list.
There are several ways you can go about it, but I'd suggest that you keep things simple and avoid using gems.
<%= link_to "New update", new_status_update_path, class: 'button' %>
Model
class StatusUpdate
belongs_to :sender, class_name: 'User'
belongs_to :mailing_list
end
Controller
class StatusUpdateController
def new
@status_update = StatusUpdate.new
end
def create
@status_update = StatusUpdate.create(status_update_params)
@status_update.mailing_list = MailingList.where(whichever_mailing_list)
if @status_update.save
redirect_to :action => "preview", :status_update => @status_update
end
end
def preview
@status_update = StatusUpdate.where(id: params[:id]).first
@mailing_list = MailingList.where(id: @status_update.mailing_list_id)
end
def send
@status_update = StatusUpdate.where(id:params[:status_update_id]).first
Mailer.status_update_email(@status_update).deliver
end
end
status_updates/new.html.erb
<%= simple_form_for(@status_update) do |f| %>
<%= f.input :title %>
<%= f.input :content, as: :text %>
<%= f.button :submit, 'Post update' %>
<% end %>
status_updates/preview.html.erb
<h1>Preview</h1>
<%= simple_form_for(@status_update, :url => url_for(:controller => 'StatusUpdateController, :action => 'send') do |f| %>
<%= f.input :subject %>
<div class="email-render-container">
<%= @status_update.content %>
</div>
<p>Make changes</p>
<%= f.input :content, as: :text %>
<%= f.button :submit, 'Approve and send emails' %>
<% end %>
If I were you, I'd do away with the preview feature. If you're loading content from a template and all you're worried about are potential duplicate content, just do this:
Controller
class StatusUpdateController
def new
@status_update = StatusUpdate.new
template = UpdateTemplate.where(however_you_assign_the_template)
@status_update.content = template.content
end
def create
@status_update = StatusUpdate.create(status_update_params)
@status_update.mailing_list = MailingList.where(whichever_mailing_list)
if @status_update.save
Mailer.status_update_email(@status_update).deliver
end
end
end
and style the new status update form with css to simulate writing on the actual email template. You'll save your users and yourself a lot of time.
wysiwyg editor
Never trust the end user with the ability to write html. Depending on your needs, I find https://www.froala.com/wysiwyg-editor easy to deploy.
differentiating buttons
Just use a preview icon with a label on your button and/or a subtitle under your button to differentiate your buttons. You don't need much command logic in your view.
Alternatively, if you think that the preview is important to your end users, just use the "preview" button as the next logical step instead of presenting your users with too many unnecessary choices.
Suggestions
Adopting a front end framework like Angularjs makes this sort of use case almost trivially easy, but it may be overkill and comes with steep learning curve if you're not familiar with it.
Upvotes: 1
Reputation: 11
Take a look at letter_opener gem. It was created by Ryan Bates, the Railscasts guy.
Upvotes: 0