Richlewis
Richlewis

Reputation: 15374

Getting Actionmailer to send an email

I have asked a question similar to this and received some great help, it has clarified some understanding and concepts.This is the first time using actionmailer so I am trying to get a better understanding

What i am trying to achieve is for an email to be to sent to a user who clicks a remind me button. It is a simple library app where a user can check out, check in and request a reminder when a book is checked back in..I’m just struggling on this last part of logic, once I see it working Im sure I will understand it better

So when the check_out status changes for a book there are various posts to the book model

Check out

<%= form_for @book do |f| %>
<%= f.label :checked_out, "Check Book Out?" %>
<%= f.check_box :checked_out, {}, true %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<%= f.hidden_field :checked_out, :value => true %>
<%= f.submit 'Checkout' %>
<% end %>

Check In

<%= form_for @book do |f| %>
<%= f.label :checked_out, "Check Book Back In" %>
<%= f.check_box :checked_out, {checked: false}, false  %>
<%= f.hidden_field :user_id, :value => nil %>
<%= f.hidden_field :checked_out, :value => false %>
<%= f.submit 'Check In' %>
<% end %>

Register Interest

<%= form_for @book do |f| %>
<%= f.label :remind_me, "let Me know when book back in" %>
<%= f.check_box :remind_me, {checked: false}, false  %>
<%= f.hidden_field :remind_me, :value => current_user.id %>
<%= f.submit 'Remind Me' %>
<% end %>

In my book model I have this logic to recognise that when a book is checked back in after a remind me request has been made an email is sent notifying the user that the book is back in the library

after_save :reminder_mailer

def reminder_mailer
if !self.checked_out && self.changes[:user_id] && self.user.nil?
ReminderMailer.remind_email(@user).deliver
end

and my action mailer

class ReminderMailer < ActionMailer::Base
default from: "my email address"

def remind_email(user)
@user = user
mail(:to => user.email, :subject => "Library Clerk")

end
end

As you can probably see I am struggling with what to pass as the users email who made the remind me request. When the remind me request is made I post the users_id to the column remind_me. I have a seperate user model (devise)..

Is part of my problem being that when the users_id is posted to the remind me column it is then just a regular integer and not linked to the users_id?

Any advice appreciated

Upvotes: 0

Views: 172

Answers (1)

Khaled
Khaled

Reputation: 2091

You could create a Reminder model (and table in DB) that keeps track of reminders that users have set

class Reminder < ActiveRecord::Base
  belongs_to :user
  belongs_to :book
end

class Book < ActiveRecord::Base
  has_many :reminders
end

Show a button beside a book, make sure to add @reminder = Reminder.new to the action that renders the following form.

<%= form_for @reminder do |f| %>
<%= f.label :remind_me, "let Me know when book back in" %>
<%= f.hidden_field :book_id, :value => @book.id %>
<%= f.submit 'Remind Me' %>
<% end %>

You will have a reminders controller, (add resources :reminders, only: [:create] to routes.rb)

class RemindersController < ApplicationController
  def create
    @book = Book.find(params[:reminder][:book_id])
    Reminder.create(user: current_user, book_id: @book.id)
    redirect_to @book
  end
end

Then in the after_save of your book model, you would send emails to all users that have reminders for this book

def reminder_mailer
  if !self.checked_out && self.changes[:user_id] && self.user.nil?
    # get all users waiting for a remind on this book
    @users = self.reminders.map(&:user)
    @users.each do |user|
      ReminderMailer.remind_email(user).deliver
    end
    # remove reminders as users have been reminded
    self.reminders.destroy_all
  end
end

Notice: Make sure that you add a validation that no user will request reminder to the same book.

Upvotes: 1

Related Questions