Reputation: 137
I am making a little app based on futureme.org for practice. The user goes to a page, sees a form, fills it out with email, subject, message, and a delivery date. Then the app delivers their message (email) on that date.
The problem I am having, is I am not sure how to set up the delivery date option in the model & in the view (ie. does rails have a date option?). Here is my code;
Letter.rb
class Letter < ActiveRecord::Base
VALID_EMAIL_REGEX = /\A[\w+\-,]+@[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates_length_of :subject, presence: true, :maximum => 30
validates_presence_of :message
validates_presence_of :deliver_on #not sure if this is right
end
Letters_Controller.rb
class LettersController < ApplicationController
def create
@letter = Letter.new(letter_params)
if @letter.save
LetterMailer.letter_confirm(@letter).deliver
redirect_to letters_path, :notice => "Your letter was sent!"
else
render "welcome/home"
end
end
private
def letter_params
params.require(:letter).permit(:email, :subject, :message)
end
end
lettermailer.rb
class Lettermailer < ActionMailer::Base
default from: "[email protected]"
def letter_confirm(letter)
mail(to: @letter.email, subject: "Thanks from Future Self")
end
def letter_email(letter)
@letter = letter
@url = 'http://futureself.herokuapp.com'
mail(to: @letter.email, subject: @letter.subject)
end
end
Home Page Form;
<%= form_for @letter, :html => {:class => 'form-horizontal'} do |f| %>
<% if @letter.errors.any? %>
<div class="error_messages">
<h3><%= pluralize(@letter.errors.count, "error")%> stopped this message from being saved</h3>
<ul>
<% @letter.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
<div class="field">
<%= f.label :email %><br />
<%= f.text_field :email %>
</div>
<div class="field">
<%= f.label :subject %><br />
<%= f.text_field :subject %><br />
</div>
<div class="field">
<%= f.label :message, "Message" %><br />
<%= f.text_area :message, size: "100x10" %>
</div>
<!-- Deliver on Option -->
<div class="field"><%= f.submit "Submit", class: "btn btn-small btn-primary" %></div>
<% end %>
</body>
</html>
Any help at all would be great.
Upvotes: 0
Views: 205
Reputation: 3529
You need a job queue, I would suggest using DelayedJob as it's about as simple as it gets (if you are using ActiveRecord) https://github.com/collectiveidea/delayed_job
Then in your LessonsController
LetterMailer.delay(run_at: @letter.deliver_on).letter_confirm(@letter)
This assumes deliver_on is a DateTime object.
Couple things you might want to consider:
Upvotes: 2
Reputation: 5973
I like to use the validates_timeliness gem. So you can do things like
validates_date :deliver_on, :before => lambda { Time.zone.now + 1.year },
:before_message => "must be earlier one year from today",
:on_or_after => lambda { Time.zone.now.end_of_day },
:on_or_after_message => "must be after today"
You can use jquery-ui-rails
f.input :deliver_on, as: :string, label: "Date of delivery (dd/mm/yyyy)", input_html: {class: "jquery-ui-date", value: f.deliver_on ? l(f.deliver_on) : nil }
Don't get me started on RegEx for email. Try googling it ;)
And yeah like @mattsmith said check out delayed job.
Upvotes: 1