RoR:InviteMailer:Class 的未定义方法“new_user_invite”

RoR: undefined method `new_user_invite' for InviteMailer:Class

我使用了以下关于创建范围邀请 (https://coderwall.com/p/rqjjca/creating-a-scoped-invitation-system-for-rails) 的教程来创建邀请、用户、组,但是 运行 出现了上述错误并且不确定如何解决。请记住我还在学习 RoR。谢谢。

我在invites_controller.rb

中有以下代码
class InvitesController < ApplicationController

  def new
    @invite = Invite.new
  end

  def create
    @invite = Invite.new(invite_params) # Make a new Invite
    @invite.sender_id = current_user.id # set the sender to the current user
    if @invite.save
       InviteMailer.new_user_invite(@invite, new_user_registration_path(:invite_token => @invite.token)).deliver #send the invite data to our mailer to deliver the email
       flash[:notice] = "Thanks, invitation has successfully been sent"
       redirect_to user_groups_url
    else
       flash[:notice] =  "oh no, creating an new invitation failed"
       redirect_to invites_path
    end
  end

  private

    def invite_params
      params.require(:invite).permit(:email, :recipient_id, :user_group_id, :sender_id)
    end

end

邀请发送令牌模型

class Invite < ApplicationRecord

  before_create :generate_token

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


end

不确定路线是否完整?

Rails.application.routes.draw do
  resources :memberships
  resources :user_groups
  # mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
  # devise_for :users
  # delete '/logout', to: 'sessions#destroy'
  default_url_options :host => "smtp.gmail.com"

  devise_for :users, controllers: {
      sessions: 'users/sessions',
      passwords: 'users/passwords',
      registrations: 'users/registrations'
  }
  get 'static_pages/index'

  resources :invites

  namespace :admin, path: '/admin' do
    resources :users, except: [:show] do
      member do
        post :resend_invite
        post :enable
      end
    end
    resources :roles, only: [:index, :edit, :update, :new, :create]
    get "audits/index"
  end
end

查看表格以邀请新用户和现有用户。

= simple_form_for @invite , :url => invites_path do |f|
  = f.error_notification
  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?

  space-left3.space-below3
    = f.hidden_field :user_group_id, :value => @invite.user_group_id
    = f.input :email, placeholder: 'user@domain.com'
  .form-actions
    button.btn.btn-primary type="submit" Send

mailer/invite_mailer.rb

class InviteMailer < ApplicationMailer
  def self.new_user_invite(invite, signup_url)
    subject    'Invite'
    recipients invite.recipient_email
    from       'example@gmail.com'
    body       :invite => invite, :signup_url => signup_url
    invite.update_attribute(:sent_at, Time.now)
  end

  def invite
    @greeting = "Hi"

    mail to: "to@example.org"
  end
end

mailer/application_mailer

 class ApplicationMailer < ActionMailer::Base
      default from: 'from@example.com'
      layout 'mailer'
    end

要在 InviteMailer 上将 new_user_invite 创建为 class 方法,您需要:

class InviteMailer < ApplicationMailer

  class << self 

    def new_user_invite(invite, path)
      ... do stuff
    end

  end

  def invite
    @greeting = "Hi"
    mail to: "to@example.org"
  end

end

或者,

class InviteMailer < ApplicationMailer

  def self.new_user_invite(invite, path)
    ... do stuff
  end

  def invite
    @greeting = "Hi"
    mail to: "to@example.org"
  end

end

使用哪种是个人喜好问题。

我想指出Jörg W Mittag想说:

I am one of those Ruby Purists who likes to point out that there is no such thing as a class method in Ruby. I am perfectly fine, though, with using the term class method colloquially, as long as it is fully understood by all parties that it is a colloquial usage. In other words, if you know that there is no such thing as a class method and that the term "class method" is just short for "instance method of the singleton class of an object that is an instance of Class", then there is no problem. But otherwise, I have only seen it obstruct understanding.

让各方都充分理解,class方法这个术语是在上面使用的口语意义上的。

不确定我是否可以解释它,但是对于邮件程序,我们只定义没有 class 语法的方法。将 mailer 视为 controller 非常方便,它们非常相似。应该是:

class InviteMailer < ApplicationMailer
  def new_user_invite(invite, signup_url)
    @signup_url = signup_url
    invite.update_attribute(:sent_at, Time.now)
    mail(to: invite.email, subject: 'Invite')
  end
end

现在您需要查看电子邮件。在 app/views/invite_mailer/ 中创建一个名为 new_user_invite.html.erb 的文件。为简单起见,它将是:

<p>Someone invited you to the project, please click link: @signup_url</p>

您还需要在邮件调用中将 new_user_registration_path 更改为 new_user_registration_url,以传递完整的 link

您可以在 guides

中阅读有关邮件程序的更多信息