Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

ruby on rails - How to generate Unsubscription link for emails of Actionmailer?

I have a table CLIENTS with id, name and email fields and I am sending them emails using ActionMailer with 3rd party SMTP.

Now I want the clients to have subscription option too so I added "subscription" column with default value as true.

Now how to generate a link which can be put in views mailer template so when the user clicks on it, the subscription value changes to false so in future the client dont' get any email ? Do note that these clients are not my rails app users so I can't uses what is been suggested here Rails 3.2 ActionMailer handle unsubscribe link in emails

I found this link how to generate link for unsubscribing from email too which looked helpful but I thought may be in 3 years, we might have got a better solution

Here is my Complete Code -

#client.rb

attr_accessible :name, :company, :email

belongs_to :user
has_many :email_ids
has_many :emails, :through => :email_ids

before_create :add_unsubscribe_hash

private

def add_unsubscribe_hash
  self.unsubscribe_hash = SecureRandom.hex
end  

Here is Clients_controller.rb file

# clients_controller.rb

  def new
    @client = Client.new

    respond_to do |format|
      format.html
      format.json { render json: @client }
      format.js
    end
  end

  def create
    @client = current_user.clients.new(params[:client])
    respond_to do |format|
      if @client.save
        @clients = current_user.clientss.all
        format.html { redirect_to @client }
        format.json { render json: @client }
        format.js
      else
        @clients = current_user.clients.all
        format.html { render action: "new" }
        format.json { render json: @client.errors, status: :error }
        format.js
      end
    end
  end

def unsubscribe
  @client = Client.find_by_unsubscribe_hash(params[:unsubscribe_hash])
  @client.update_attribute(:subscription, false)
end

The code is working fine for existing records and the unsubscription is working perfectly, I am only having problem in creating new clients.

I have used @client in unsubscribe method as I am using this object in client_mailer.rb template (using @client or just using client, both are working!)

EDIT 2 - _form.html.erb

<%= simple_form_for(@client, :html => {class: 'form-horizontal'}) do |f| %>

    <%= f.input :name, :label => "Full Name" %>
    <%= f.input :company %>
    <%= f.input :email %>
    <%= f.button :submit, class: 'btn btn-success' %>
<% end %>

I have copied the full track stack at http://jsfiddle.net/icyborg7/dadGS/

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try associating each client with a unique, but obscure, identifier which can be used to look up (and unsubscribe) the user via the unsubscribe link contained within the email.

Start by adding another column to your clients table called unsubscribe_hash:

# from command line
rails g migration AddUnsubscribeHashToClients unsubscribe_hash:string

Then, associate a random hash with each client:

# app/models/client.rb
before_create :add_unsubscribe_hash

private

def add_unsubscribe_hash
    self.unsubscribe_hash = SecureRandom.hex
end

Create a controller action that will toggle the subscription boolean to true:

# app/controllers/clients_controller.rb
def unsubscribe
    client = Client.find_by_unsubscribe_hash(params[:unsubscribe_hash])
    client.update_attribute(:subscription, false)
end

Hook it up to a route:

# config/routes.rb
match 'clients/unsubscribe/:unsubscribe_hash' => 'clients#unsubscribe', :as => 'unsubscribe'

Then, when a client object is passed to ActionMailer, you'll have access to the unsubscribe_hash attribute, which you can pass to a link in the following manner:

# ActionMailer view
<%= link_to 'Unsubscribe Me!', unsubscribe_url(@user.unsubscribe_hash) %>

When the link is clicked, the unsubscribe action will be triggered. The client will be looked up via the passed in unsubscribe_hash and the subscription attribute will be turned to false.

UPDATE:

To add a value for the unsubscribe_hash attribute for existing clients:

# from Rails console
Client.all.each { |client| client.update_attribute(:unsubscribe_hash, SecureRandom.hex) }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...