【问题标题】:How to create a "Send this Newsletter by Email" button to send a Newsletter to all users (Rails)如何创建“通过电子邮件发送此时事通讯”按钮以向所有用户发送时事通讯(Rails)
【发布时间】:2015-09-24 07:14:27
【问题描述】:

编辑:已解决,请在下面查看我的答案。

所以我创建了一个名为 newsletter 的脚手架,网站所有者将能够创建、编辑、销毁等。当他们对该时事通讯感到满意时,他们将能够通过按下按钮将其发送出去这将调用NewslettersController#send。当我为测试目的制作邮件和时事通讯时,我最初的 .deliver_now 位位于 NewslettersController#create 下。但是,当我尝试将其移至send 方法时,突然间在我的NewslettersController#indexnew 等上。我收到一条错误消息,指出Mailer 的视图无法访问Newsletter 的属性。为什么会发生这种情况?为什么它只适用于 create 方法?

作为参考,Mailer 称为Monthly,脚手架为Newsletter

错误:

NoMethodError in Newsletters#index
undefined method `subject' for nil:NilClass

  <body>
    <h1>Hello</h1>
    <p><%= @newsletter.subject %></p>
    <p><%= @newsletter.body %></p>
    <p><%= @newsletter.link %></p>
  </body>

NewslettersController

  def send(monthly)
    Monthly.monthly(@newsletter).deliver_now
  end

monthly.html.erb(发件人的观点)

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hello</h1>
    <p><%= @newsletter.subject %></p>
    <p><%= @newsletter.body %></p>
    <p><%= @newsletter.link %></p>
  </body>
</html>

相关日志:

Started GET "/newsletters" for 127.0.0.1 at 2015-07-06 20:08:04 -0400
Started GET "/newsletters" for 127.0.0.1 at 2015-07-06 20:08:04 -0400
Processing by NewslettersController#index as HTML
Processing by NewslettersController#index as HTML
   (0.2ms)  SELECT "users"."email" FROM "users"
   (0.2ms)  SELECT "users"."email" FROM "users"
  Rendered monthly/monthly.html.erb within layouts/mailer (1.2ms)
  Rendered monthly/monthly.html.erb within layouts/mailer (1.2ms)

Monthly#monthly: processed outbound mail in 8.3ms

Monthly#monthly: processed outbound mail in 8.3ms
Completed 500 Internal Server Error in 14ms (ActiveRecord: 0.9ms)
Completed 500 Internal Server Error in 14ms (ActiveRecord: 0.9ms)

ActionView::Template::Error (undefined method `subject' for nil:NilClass):
     5:   </head>
     6:   <body>
     7:     <h1>Hello</h1>
     8:     <p><%= @newsletter.subject %></p>
     9:     <p><%= @newsletter.body %></p>
    10:     <p><%= @newsletter.link %></p>
    11:   </body>
  app/views/monthly/monthly.html.erb:8:in `_app_views_monthly_monthly_html_erb___3456442674425673730_70162508652140'
  app/mailers/monthly.rb:4:in `monthly'
  app/controllers/newsletters_controller.rb:8:in `send'



ActionView::Template::Error (undefined method `subject' for nil:NilClass):
     5:   </head>
     6:   <body>
     7:     <h1>Hello</h1>
     8:     <p><%= @newsletter.subject %></p>
     9:     <p><%= @newsletter.body %></p>
    10:     <p><%= @newsletter.link %></p>
    11:   </body>
  app/views/monthly/monthly.html.erb:8:in `_app_views_monthly_monthly_html_erb___3456442674425673730_70162508652140'
  app/mailers/monthly.rb:4:in `monthly'
  app/controllers/newsletters_controller.rb:8:in `send'

如果我遗漏了一些信息,请告诉我

编辑:添加monthly.rb

class Monthly < ApplicationMailer
    def monthly(newsletter)
        @newsletter = newsletter
        mail to: User.pluck(:email)

    end
end

编辑 2:添加 before_action :set_newsletter

before_action :set_newsletter, only: [:send, :show, :edit, :update, :destroy]
def set_newsletter
  @newsletter = Newsletter.find(params[:id])
end

编辑 3:新问题。 我不再遇到 index 或 show 方法的错误,但在尝试发送 通讯。以下是代码,但请注意,名称已更改 为了更加不言自明。

错误:

undefined method `subject' for nil:NilClass

<body>
    <h1>Hello</h1>
    <p><%= @newsletter.subject %></p>
    <p><%= @newsletter.body %></p>
    <p><%= @newsletter.link %></p>
</body>

NewslettersController#send_newsletter

  def send_newsletter
    Monthly_Mailer.monthly(@newsletter).deliver_now
    flash[:notice] = "Newsletter has been sent."
    redirect_to newsletter_path(@newsletter.id)
  end

路线

get :send_newsletter, to: 'newsletters#send_newsletter', as: :send_newsletter

Monthly_Mailer.rb

class Monthly_Mailer < ApplicationMailer
    def monthly(newsletter)
        @newsletter = newsletter
        mail to: User.pluck(:email)
    end
end

show.html.erb上发送时事通讯的按钮

<%= link_to "Send Newsletter by email", :controller => "newsletters", :action => "send_newsletter", :id => @newsletter.id %>

相关日志条目显示newsletter.id 被正确传递:

Processing by NewslettersController#send_newsletter as HTML
  Parameters: {"id"=>"1"}

【问题讨论】:

  • 在您的控制器中设置@newsletter 的代码在哪里? monthly 方法是什么样的?
  • @cschroed @newsletter 使用 before_action :set_newsletter private 方法设置,rails 使用该方法默认为所有 CRUD 操作设置 @newsletter。我在编辑中添加了monthly.rb。感谢您的回复。
  • 您能在此处包含before_actionset_newsletter 和操作代码吗?通常,像index 这样的操作不会设置单个@newsletter,而是设置@newsletters 的集合。
  • @cschroed set_newsletter 不会在 index 之前调用,仅在需要引用特定时事通讯的操作之前调用。检查EDIT 2 的代码。如果我说它是在index 之前调用的,我为错误传达道歉
  • 您的日志显示Processing by NewslettersController#indexindex 是调用NewslettersController#send 然后调用Monthly.monthly 的操作吗?

标签: ruby-on-rails attributes actionmailer sendgrid newsletter


【解决方案1】:

如何创建“通过电子邮件发送此通讯”

这将允许您的用户像任何帖子一样创建、编辑和删除时事通讯,然后在他们满意后将其发送出去。

这假设您已经设置好 environment 文件,并且可以通过 Rails 应用成功发送电子邮件。

注意 应该注意的是,您需要为生产进行一些更改。例如,将时事通讯发送给所有用户是不好的做法。您应该考虑创建一个布尔值,他们可以检查他们是否愿意接收时事通讯,然后将其发送给所有这些用户。

步骤:

  1. 为 Newsletter 和 Mailer 创建支架。
  2. 为您的 Newsletter 类创建一个自定义方法,当您按下“通过电子邮件发送此 Newsletter”按钮时,您将调用该方法。
  3. 修改您的邮件程序以创建一个操作,将您的时事通讯发送给您的所有用户。
  4. 创建邮件程序的视图。
  5. 添加您将用于“发送此简报”按钮的路由。
  6. 将链接添加到时事通讯的show.html.erb,这将允许您的客户发送时事通讯。

步骤 1. 生成脚手架和邮件

我假设您可以自己完成大部分工作。

请务必为您的邮件程序指定一个与您的脚手架不同的名称,否则您会遇到一些冲突。我为我的脚手架选择了Newsletter,为我的邮件选择了Monthly

$ rails g scaffold Newsletter subject:string body:text link:string

$ rails g mailer Monthly

步骤 2. 在NewslettersController中创建自定义方法

接下来,创建一个在您的客户想要发送时事通讯时调用的方法。另一种方法是将此代码附加到NewslettersController#create 方法,但在发送之前无法修改时事通讯。

  def send_newsletter

#Let's take a close look at this line below
    Monthly_Mailer.monthly(@newsletter).deliver_now

    flash[:notice] = "Newsletter has been sent."
    redirect_to newsletter_path(@newsletter.id)
  end

注意事项: Monthly_Mailer 引用了/app/mailers 中的文件名,该文件在您生成邮件时创建。 monthly 引用了将发送邮件的方法,我们将在 Monthly_Mailer 中创建该方法

第 3 步:修改您的邮件

class Monthly_Mailer < ApplicationMailer
    def monthly(newsletter)
        @newsletter = newsletter
        mail to: User.pluck(:email)
    end
end

User.pluck(:email) 更改为您自己的邮件列表,可能使用介绍说明中的建议。截至目前,这段代码会将邮件发送给所有用户,即使他们不想要时事通讯。再加上电子邮件中没有Unsubscribe 链接这一事实,这意味着这是不道德的,并且可能违反法律。

第 4 步:创建邮件者视图

当您生成邮件时,它应该在您的/app/views/ 目录中创建了一个文件夹monthly_mailer。根据您用于生成器的选项,它甚至可能创建了monthly.html.erbmonthly.text.erb。如果没有,请立即创建。您必须自己为 HTML 文件设置样式,但我已经包含了一些基本内容。 TEXT 文件将用作 HTML 文件的替代文件,并且不包含任何 HTML 样式。我强烈建议您同时包含 HTML 和 TEXT 版本。

您的monthly.html.erb 文件可能如下所示:

<!DOCTYPE html>
<html>
  <head>
    <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
  </head>
  <body>
    <h1>Hello</h1>
    <p><%= @newsletter.subject %></p>
    <p><%= @newsletter.body %></p>
    <p><%= @newsletter.link %></p>
  </body>
</html>

对于monthly.text.erb,想象与 HTML 文件相同,但没有任何 HTML。

第 5 步:添加将用于“通过电子邮件发送此新闻稿”链接的路由。

get :send_newsletter, to: 'newsletters#send_newsletter', as: :send_newsletter

newsletters#send_newsletter 引用了我们在NewslettersController 中创建的自定义方法

第 6 步:在时事通讯的 show.html.erb 中添加链接

<%= link_to "Send Newsletter by email", :controller => "newsletters", :action => "send_newsletter", :id => @newsletter %>

第 7 步

没有第 7 步。尽情享受吧。请随时提交更正或建议。我知道这并不完美,但它确实有效。

【讨论】:

    猜你喜欢
    • 2013-11-13
    • 2012-03-08
    • 2012-02-25
    • 1970-01-01
    • 2015-05-20
    • 2012-07-23
    • 2016-02-18
    • 2016-02-21
    • 2012-06-25
    相关资源
    最近更新 更多