konchanxxx / menta

MENTAのタスク管理用リポジトリ
0 stars 0 forks source link

Deviseを使っているユーザーにEmailを送る。 #16

Closed sumura80 closed 5 years ago

sumura80 commented 5 years ago

概要

Userの登録にDeviseを使用しています。 今回、アクションがあるたびにUserにEmailを送りたいと考えております。 Action mailerでEmailを送ることを検討しております。

実現したいこと

下記の3アクション時にメール機能を追加したい。 ※Userに届くメール。 1.新規登録時の“Welcome” email 2.Email変更時の“Updated” email

※Userからadmin(自分)に届くメール。 3.問い合わせフォームからemail

困っていること

通常のAction mailerを実装する時には、UsersコントローラのcreateアクションにMailerメソッドを追加しているようです。 `SampleMailer.send_when_create(@user).deliver`

ですが、Deviseを使用すると、このusersコントローラの"Createアクション"が存在しません。 記事によっては、Userのモデルに"after_create, after_update"などで記述する方法。 またDeviseのRegistrations controllerをoverrideする方法などもありました。

どれも基本的なAction mailerのやり方からずれているので、どのような方法で進めれば良いかわかりません。

お忙しいところ恐れ入りますが、ご教示ただけませんでしょうか? よろしくお願い致します。

konchanxxx commented 5 years ago

Deviceのドキュメントを確認するとコントローラーのアクションをカスタムできるようなのでカスタマイズしたアクションでmailerの処理を呼び出せば良いかなと思いました。 https://github.com/plataformatec/devise#configuring-controllers

Userのモデルに"after_create, after_update"などで記述する方法

こちらの方法でも実装できますね。これはcallbackという手法です。 https://railsguides.jp/active_record_callbacks.html

前者は、登録などの処理に紐づけてmailerの処理を実装する方式で、後者はDBにinsertされたタイミングで処理するという方法です。 どちらの方法でも実際のアプリケーションだと動きしては同じになるかと思いますが、後者の場合は登録処理以外でもレコードが生成、更新されたタイミングでメールが送信されるので本来の登録に対してメールを送信するといった文脈から考えると前者の実装の方が妥当だと思います:bow:

sumura80 commented 5 years ago

早急なご回答ありがとうございます。 コントローラーのオーバーライドがやっぱり良さそうなんですね。

このように、Deviseを使用して、Welcomeメールといったような流れは、実務では使うことはよくありますか?

sumura80 commented 5 years ago

Deviseで新規登録者に確認メールを送る機能を実装しております。 実装したのですが、新規登録したにもかかわらずメールが飛んでこない状態で困っております。

今回、下記の方法でコントローラーのアクションをオーバーライドする方法を取りました。 https://github.com/plataformatec/devise#configuring-controllers 1.でrails g devise:controllers usersのようにcontrollerを作成しました。

2.Tell the router to use this controller: devise_for :users, controllers: { sessions: 'users/sessions' } この箇所で、エラーが発生しました。こちらは、以前にdeviseでuserを登録しているので不要なのかなと思いました。 defined_2_routes

3.Copy the views from devise/sessions to users/sessions. Since the controller was changed, it won't use the default views located in devise/sessions. これですが、これは新しくViewを作成する必要がありますか?

下記も参考 https://easyramble.com/welcome-mail-with-devise.html

こちらに最新版のアプリをアップしてたので、ご確認いただけませんでしょうか。よろしくお願い致します。:bow::bow: https://github.com/sumura80/med_plus_bs4_updated_master/pull/5

konchanxxx commented 5 years ago

コントローラーのオーバーライドがやっぱり良さそうなんですね。

ケースバイケースだと思います。deviseはカスタムするのが結構大変とよくきくので極力オーバーライドしないほうが良いとは思いますが今回のようなケースくらいなら複雑ではないので大丈夫かなと思います:bow:

このように、Deviseを使用して、Welcomeメールといったような流れは、実務では使うことはよくありますか?

自分は実務では使ったことないですが、使っているシステムもたくさんありますね。有名どころだとhttps://github.com/Sorcery/sorcery とかでしょうか。

konchanxxx commented 5 years ago

2.Tell the router to use this controller: devise_for :users, controllers: { sessions: 'users/sessions' } この箇所で、エラーが発生しました。こちらは、以前にdeviseでuserを登録しているので不要なのかなと思いました。

new_user_session はすでに定義済みと書いてありますね。rails routes -g new_user_session でルーティングが定義されているかどうか見た方が良いと思います。

3.Copy the views from devise/sessions to users/sessions. Since the controller was changed, it won't use the default views located in devise/sessions. これですが、これは新しくViewを作成する必要がありますか?

これはデフォルトで使われていたviewがdevise/sessions配下から今回作成したusersの配下に移ったということなのでcopyするか新しく作る必要があると思います。

konchanxxx commented 5 years ago

@sumura80 こちら回答内容okでしょうか?

sumura80 commented 5 years ago

ご連絡ありがとうございます。 こちら進行中なので、もう少しお待ちいただけませんでしょうか? よろしくお願い致します。:bow:

konchanxxx commented 5 years ago

了解ですー問題ありません:smile:ありがとうございます:bow:

sumura80 commented 5 years ago

ご回答ありがとうございました。:bow: 現在下記のエラーでまだ止まっている状況です。

2.Tell the router to use this controller: devise_for :users, controllers: { sessions: 'users/sessions' } この箇所で、エラーが発生しました。こちらは、以前にdeviseでuserを登録しているので不要なのかなと思いました。

new_user_session はすでに定義済みと書いてありますね。rails routes -g new_user_session でルーティングが定義されているかどうか見た方が良いと思います。

今回routeにこの行を確認したところすでに定義済みとなっておりました。

          Prefix Verb URI Pattern              Controller#Action
new_user_session GET  /users/sign_in(.:format) devise/sessions#new

しかしこれは、以前作成したDeviseのrouteであり、現在はdevise/sessions から users/sessionにviewが移動しております。 下記のように記述すると画像のようなArgumentErrorが発生してしまいます。

config/routes.rb

devise_for :users
devise_for :users, controllers: { sessions: 'users/sessions' } 

argumenterror

ダブって記述しているので、エラーになるのは理解できるのですが、一つ目のdevise_for :usersを削除するとサインインなどができなくなります。(エラーがでます) ですが今回は、二つ目のrouteを使う必要があります。

エラー画面に表示されているRailsガイドも参考にしましたが、わかりにくかったです。:sweat: https://railsguides.jp/routing.html#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E4%BD%9C%E6%88%90%E3%82%92%E5%88%B6%E9%99%90%E3%81%99%E3%82%8B

他のサイトでは、一つ目のrouteを削除すれば良いと書いてありましたが、それではうまくいきませんでした。 https://stackoverflow.com/questions/18016761/rails-4-devise-invalid-route-name-already-in-use ご教示いただけませんでしょうか?よろしくお願い致します。:cold_sweat:

sumura80 commented 5 years ago

@rexitorg お疲れ様です。 なんとか質問させていただいたエラーは自走することができました。

現在、Action mailerでメール機能を実装ちゅうです。 内容としては、新規ユーザーがサインアップすると、ユーザーにWelcomeメールが届くといった内容です。

そこで、下記のようなエラーで出てしまっております。 action_mailer_01

/app/mailers/user_mailer.rb には、下記のように記述したのですが、どこがおかしいかわからない状態です。 ご教示いただけませんでしょうか?よろしくお願い致します。:bow:


class UserMailer < ApplicationMailer

  # Subject can be set in your I18n file at config/locales/en.yml
  # with the following lookup:
  #
  #   en.user_mailer.signup_confirmation.subject
  #

  def signup_confirmation(user)
    @user = user
    @greeting = "Hi"

    mail (
       from: 'codetest1980@gmail.com',
       to: @user.email,
       subject: "Sign Up Confirmation"

      )
  end
end
```
sumura80 commented 5 years ago

@rexitorg こちら、create時のエラーが解決致しました。 次は、updateのemail変更時に取りかかりますので、もう少しクローズせずにお待ちいただければと思います。:bow:

sumura80 commented 5 years ago

@rexitorg こちらローカルでupdate時のメールも遅れましたので、クローズさせていただきます。 ありがとうございました。