3
votes

In my Rails app, I have an Invite model:

class Invite < ActiveRecord::Base
  belongs_to :calendar
  belongs_to :sender, :class_name => 'User'
  belongs_to :recipient, :class_name => 'User'

  before_create :generate_token

  def generate_token
    self.token = Digest::SHA1.hexdigest([self.calendar_id, self.recipient_role, Time.now, rand].join)
  end

end

With the following migration:

class CreateInvites < ActiveRecord::Migration
  def change
    create_table :invites do |t|
      t.string :email 
      t.integer :calendar_id
      t.integer :sender_id
      t.integer :recipient_id
      t.string :recipient_role
      t.string :token
      t.timestamps null: false
    end
  end
end

I use the Invite model to create invitations, through the following InvitesController:

class InvitesController < ApplicationController
  def create
    @invite = Invite.new(invite_params) # Make a new Invite
    @invite.sender_id = current_user.id # set the sender to the current user
    @calendar = Calendar.find_by_id(@invite.calendar_id)
    authorize @calendar
    if @invite.save
      InviteMailer.invite(@invite).deliver #send the invite data to our mailer to deliver the email
    else
      format.html { render :edit, notice: 'Invitation could not be sent.' }
    end
    redirect_to calendar_path(@calendar)
  end

  private

  def invite_params
    params.require(:invite).permit(:email, :calendar_id)
  end

end

Here is the InviteMailer:

class InviteMailer < ApplicationMailer

  def invite(invite)
    @link = new_user_registration_path invite_token: invite.token
    mail to: invite.email, subject: "Calendy Invitation"
  end

end

And here is the corresponding mailer view:

You've been invited to join a calendar.
Click here to view this calendar: <%= @link %>

When I create an invite and I check the logs on my server, I can see that the following email has been generated by the mailer:

InviteMailer#invite: processed outbound mail in 13.7ms

Sent mail to [email protected] (57.6ms)
Date: Tue, 15 Sep 2015 10:50:13 -0700
From: [email protected]
To: [email protected]
Message-ID: <[email protected]>
Subject: Calendy Invitation
Mime-Version: 1.0
Content-Type: text/html;
 charset=UTF-8
Content-Transfer-Encoding: 7bit

<html>
  <body>
    You've been invited to join a calendar.
Click here to view this calendar: /account/sign_up?invite_token=cf7fb2ab8ad0774a99c1cdf7baf0bd44796c2f0f
  </body>
</html>

Redirected to http://localhost:3000/calendars/3

I had two problems here:

  1. I don't understand why I have /account/sign_up?invite_token=cf7fb2ab8ad0774a99c1cdf7baf0bd44796c2f0f in the email and not http://localhost:3000/calendars/3/account/sign_up?invite_token=cf7fb2ab8ad0774a99c1cdf7baf0bd44796c2f0f

  2. I am not sure that the above link, generated by <%= @link %>, is clickable. And when I try to make it clickable, with <%= link_to @link %>, as recommended here, I get the following error:

    ActionController::UrlGenerationError in Invites#create No route matches {:action=>"index"}

    You've been invited to join a calendar. Click here to view this calendar: <%= link_to @link %>

With the error coming from the line Click here to view this calendar: <%= link_to @link %>

I would highly appreciate any insight regarding the above items.

Any idea?

1
@link = new_user_registration_url invite_token: invite.token instead of @link = new_user_registration_path invite_token: invite.tokenWeezHard

1 Answers

4
votes

Use new_user_registration_url instead of new_user_registration_path

_path helpers provide a site-root-relative path. You should probably use this most of the time.

_url helpers provide an absolute path, including protocol and server name. I've found that I mainly use these in emails when creating links to the app on the server. They should mainly be used when providing links for external use. (Think email links, RSS, and things like the copy and paste URL field under a YouTube video's "Share" section.)

And use link_to in mailer class is a bad thing

class InviteMailer < ApplicationMailer

  def invite(invite)
    @invite = invite
    mail to: invite.email, subject: "Calendy Invitation"
  end

end

Mailer view:

Click here to view this calendar: <%= link_to "link", new_user_registration_url(invite_token: @invite.token) %>