0

ユーザー アカウントが確認されているかどうかを Devise が判断する方法を変更する必要があります。

ユーザーが電子メールを入力し、電子メールのリンクをクリックしてパスワードを設定する 2 段階の登録をセットアップしました。

これは正常に機能しますが、ログインしたユーザーがユーザーを作成し、アカウントを確認するためのリンクを送信できるシナリオがあります。これは、カスタム メーラーを介して手動で送信されます (これには、アカウントを要求したユーザーのメール アドレスと、confirmation_token が含まれます)。これは、アカウントが別のユーザーを介して作成された場合、ユーザーは 2 つのメールを受け取ることを意味します。カスタムメール「招待」。

これに続いて、skip_confirmation を設定しました! 保存する前に、送信したメールのみがユーザーに届くことを意味しますが、これにより confimed_at フィールドが設定されるため、アカウントが既に確認されているというエラーが生成されるため、ユーザーはパスワードを設定できません。

確認済みを変更するにはどうすればよいですか? パスワードがnullでないことも確認する方法は?

これが私の2ステップ登録プロセスのオーバーライドされた確認コントローラーです:

class ConfirmationsController < Devise::ConfirmationsController
  def show
    self.resource = resource_class.find_by_confirmation_token(params[:confirmation_token])
    super if resource.confirmed? 
  end

  def confirm
    self.resource = resource_class.find_by_confirmation_token(params[resource_name][:confirmation_token])
    if resource.update_attributes(params[resource_name].except(:confirmation_token)) && resource.password_match?
      self.resource = resource_class.confirm_by_token(params[resource_name][:confirmation_token])
      set_flash_message :notice, :confirmed
      sign_in_and_redirect(resource_name, resource)
    else
      render :action => "show"
    end
  end
end

カスタムメーラーは次のとおりです。

class MyMailer < Devise::Mailer   
  helper :application # gives access to all helpers defined within `application_helper`.


   def invite(sender, recipient)
        @sender = sender
        @recipient = recipient

        mail( :to => recipient.email,
              :subject => "Account created by #{sender.email}",
              :from => "noreply@noreply.com"
            )
  end

end

ログインしたユーザーが新しいユーザーを作成するコントローラーのコード (該当するセクションを表示)

.
.
.
            newContact = User.create(:email => params[:contact_email])
            newContact.skip_confirmation!
            if newContact.save
                 MyMailer.invite(current_user, newContact).deliver
                 .
                 .
                 .
             end
.
.
.
4

1 に答える 1

0

だから私はこれをハッキングしてこれをうまく機能させることができたので、どうやってそこにたどり着いたかを共有したいと思いました。

したがって、要件は次のとおりです。

1)ユーザーは登録ページからサインアップします。確認のために送信される電子メールは、標準のconfirmation_instructionsデバイスの電子メールです。

2)ユーザーは別のユーザーによって作成され、送信される電子メールは、作成者のユーザー名を送信者に含むカスタムメールです。

これを機能させるために、上記に次の変更を加えました。

ユーザーテーブルに列を追加しました:invited:Integer

ユーザーモデルに以下を追加しました。

protected
  def send_confirmation_instructions
    if !self.invited.nil?
      self.confirmation_token = nil if reconfirmation_required?
      @reconfirmation_required = false
      generate_confirmation_token! if self.confirmation_token.blank?
    else
      self.confirmation_token = nil if reconfirmation_required?
      @reconfirmation_required = false
      generate_confirmation_token! if self.confirmation_token.blank?
      self.devise_mailer.confirmation_instructions(self).deliver
    end
  end

  def send_on_create_confirmation_instructions
    self.devise_mailer.confirmation_instructions(self).deliver if self.invited.nil?
  end

ログインしたユーザーによってユーザーが作成されたコントローラーで、

.
.
.
            newContact = User.create(:email => params[:contact_email], :invited => 1)
            if newContact.save
                 MyMailer.invite(current_user, newContact).deliver
                 .
                 .
                 .
             end
.
.
.

また、ユーザーが確認リンクを再度クリックする可能性に対処するために、ConfirmationsControllerに以下を追加しました。

  def show
    self.resource = resource_class.find_by_confirmation_token(params[:confirmation_token])
    if self.resource.nil?
      redirect_to new_user_session_path, :notice => 'This link is no longer active, please sigin in or request new password'
    else
      super if resource.confirmed?
    end
  end

より良い方法があると確信していますが、これは私たちが必要としているものに対して機能します。誰かがより良い方法を提案したいなら、ぜひ私のゲストになってください。

于 2012-11-23T22:38:58.410 に答える