Rails mailer has issues with session persistence and with sending email

北战南征 提交于 2020-01-05 07:01:11

问题


I'm working through Ryan Bates' Railscast #124: Beta Invitations. I've got all the code in place, but I still two problems.

  1. Sessions don't persist through the email sending process. For some reason, when a signed in user sends an invite to a friend, the app signs out the user.
  2. Signed in users can't send email. I get an error message about having the wrong number of arguments.

I don't think these two problems are related, but on the off chance they are, I thought I should mention both. Does any one have any ideas why I'm encountering these two problems?

Error message when sending email invite as a signed in user:

    ArgumentError in InvitationsController#create

    wrong number of arguments (0 for 2)
    Rails.root: /*********/MyApp

    Application Trace | Framework Trace | Full Trace
    app/mailers/user_mailer.rb:10:in `invitation'
    app/controllers/invitations_controller.rb:16:in `create'

Controller

class InvitationsController < ApplicationController

  def new
    @invitation = Invitation.new
  end

  def create
    @invitation = Invitation.new(params[:invitation])
    @invitation.sender = current_user
    if @invitation.save
      if current_user?(nil) 
         flash[:notice] = "Thank you, we will notify when we are ready."
         redirect_to root_path       
      else
        UserMailer.invitation.(@invitation, signup_path(@invitation.token)).deliver
        flash[:notice] = "Thank you, invitation sent."
        redirect_to hunts_path 
      end
    else
      render :action => 'new'
    end
  end

end

mailers/User_Mailer.rb. Line 10 is the one that says "def invitation(invitation, signup_path)."

class UserMailer < ActionMailer::Base
  default :from => "********"

  def registration_confirmation(user)
    @user = user
    attachments["rails.png"] = File.read("#{Rails.root}/app/assets/images/rails.png")
    mail(:to => "#{user.name} <#{user.email}>", :subject => "Registered")
  end

  def invitation(invitation, signup_path)
    subject    'Invitation'
    recipients invitation.recipient_email
    body       :invitation => invitation, :signup_url => signup_path
    invitation.update_attribute(:sent_at, Time.now)
  end


end

models/invitation.rb

class Invitation < ActiveRecord::Base

  belongs_to :sender, :class_name => 'User'
  has_one :recipient, :class_name => 'User'

  validates_presence_of :recipient_email
  validate :recipient_is_not_registered
  validate :sender_has_invitations, :if => :sender

  before_create :generate_token
  before_create :decrement_sender_count, :if => :sender

  private

  def recipient_is_not_registered
    errors.add :recipient_email, 'is already registered' if User.find_by_email(recipient_email)
  end

  def sender_has_invitations
    unless sender.invitation_limit > 0
      errors.add_to_base 'You have reached your limit of invitations to send.'
    end
  end

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

  def decrement_sender_count
    sender.decrement! :invitation_limit
  end

end

Routes.rb

resources :users, :invitations
resources :sessions, :only => [:new, :create, :destroy]

match '/signup/',  :to => 'users#new'
match '/signup/:invitation_token', :to => 'users#new'
match '/signin',  :to => 'sessions#new'
match '/signout', :to => 'sessions#destroy'
match '/contact', :to => 'pages#contact'
match '/about',   :to => 'pages#about' 
match '/help',    :to => 'pages#help'

root :to => "pages#home"
match ':controller(/:action(/:id(.:format)))'

回答1:


Alright, so this is causing the Session persistence problem:

Invitation Model in invitation.rb, relevant parts

belongs_to :sender, :class_name => 'User'
[...]
before_create :decrement_sender_count, :if => :sender
[...]
def decrement_sender_count
  sender.decrement! :invitation_limit
end

After reviewing the logs I saw that the decrement! method somehow thinks it's funny to update the remember_token in the database as well. Then the remember_token in the cookie is not valid anymore. The first ugly workaround I came up with is this:

def decrement_sender_count
  # sender.decrement! :invitation_limit
  limit = sender.invitation_limit
  sender.update_attributes(:invitation_limit => (limit.to_i-1))      
end

I'll ask another question to find out what's up with ActiveRecord there. See better answer here.




回答2:


If you've copied this straight from your code, you have an extra dot which is causing your exception in this line:

UserMailer.invitation.(@invitation, signup_path(@invitation.token)).deliver

There should be no dot between invitation and (



来源:https://stackoverflow.com/questions/10064057/rails-mailer-has-issues-with-session-persistence-and-with-sending-email

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!