【问题标题】:2 forms on same page, Sending using Pony in Sinatra, same email address同一页面上的 2 个表单,在 Sinatra 中使用 Pony 发送,相同的电子邮件地址
【发布时间】:2013-02-07 11:46:00
【问题描述】:

我正在使用 Pony.mail 在 Sinatra 中发送邮件,我现在有两种形式,一种只发送电子邮件地址用于订阅时事通讯,第二种形式是联系表,两者都在执行相同的操作.

我想要实现的是,如果订阅字段已完成,则仅发送这些参数,或者如果联系表已完成并发送,则发送这些参数

这是我到目前为止想出的,但是得到未定义的方法 nil

 post '/' do
  require 'pony'
 Pony.mail(
 :from => params[:name] || params[:subscribe],
 :to => 'myemailaddress',
 :subject => params[:name] + " has contacted you via the Website" ||  params[:subscribe] + " has subscribed to the newsletter",
 :body => params[:email] + params[:comment],
 :via => :smtp,
 :via_options => {
 :address              => 'smtp.gmail.com',
 :port                 => '587',
 :enable_starttls_auto => true,
 :user_name            => 'myemailaddress',
 :password             => 'mypassword',
 :authentication       => :plain, 
 :domain               => "localhost.localdomain" 
 })
  redirect '/success' 
 end

这是否可能,或者每个表格都必须单独处理?

谢谢

【问题讨论】:

    标签: ruby forms sinatra pony


    【解决方案1】:

    我会经历几个阶段来重构这段代码。

    1。提取正在变化的东西(并使它们更 Rubyish)

    post '/' do
      require 'pony'
    
      from = params[:name] || params[:subscribe]
      subject = "#{params[:name]} has contacted you via the Website" ||
                "#{params[:subscribe]} has subscribed to the newsletter"
      body = "#{params[:email]}#{params[:comment]}"
    
      Pony.mail(
        :from => from,
        :to => 'myemailaddress',
        :subject => subject,
        :body => body,
        :via => :smtp,
        :via_options => {
        :address              => 'smtp.gmail.com',
        :port                 => '587',
        :enable_starttls_auto => true,
        :user_name            => 'myemailaddress',
        :password             => 'mypassword',
        :authentication       => :plain, 
        :domain               => "localhost.localdomain" 
      })
      redirect '/success' 
    end
    

    2。明确你的意图

    在这种情况下,代码中有两个分支。

    post '/' do
      require 'pony'
    
      if params[:name] # contact form
        from = params[:name]
        subject = "#{params[:name]} has contacted you via the Website"
      else # subscription form
        from = params[:subscribe]
        subject = "#{params[:subscribe]} has subscribed to the newsletter"
      end
    
      body = "#{params[:email]}#{params[:comment]}"
    
      Pony.mail(
        :from => from,
        :to => 'myemailaddress',
        :subject => subject,
        :body => body,
        :via => :smtp,
        :via_options => {
        :address              => 'smtp.gmail.com',
        :port                 => '587',
        :enable_starttls_auto => true,
        :user_name            => 'myemailaddress',
        :password             => 'mypassword',
        :authentication       => :plain, 
        :domain               => "localhost.localdomain" 
      })
      redirect '/success' 
    end
    

    (我不太喜欢在条件分支中设置本地变量,但为了清楚起见我们将忽略这一点。我可能会在条件之前创建一个散列,并使用已经完成的键,然后将其填充到分支,但 YMMV。)

    3。从不变的内容中提取不变的内容。

    Sinatra 有一个 configure 块来处理这种事情。

    require 'pony'
    
    configure :development do
      set :email_options, {
        :via => :smtp,
        :via_options => {
        :address              => 'smtp.gmail.com',
        :port                 => '587',
        :enable_starttls_auto => true,
        :user_name            => 'myemailaddress',
        :password             => 'mypassword',
        :authentication       => :plain, 
        :domain               => "localhost.localdomain" 
      }
    end
    
    Pony.options = settings.email_options
    

    请注意,我已添加 :development,因为您可能希望为生产设置不同的设置。

    现在你的路线更干净,更容易调试:

    post '/' do
    
      if params[:name] # contact form
        from = params[:name]
        subject = "#{params[:name]} has contacted you via the Website"
      else # subscription form
        from = params[:subscribe]
        subject = "#{params[:subscribe]} has subscribed to the newsletter"
      end
    
      body = "#{params[:email]}#{params[:comment]}"
    
      Pony.mail
        :from => from,
        :to => 'myemailaddress',
        :subject => subject,
        :body => body,
    
      redirect '/success' 
    end
    

    我的最后一个提示是将尽可能多的 Pony 选项放入 ENV 变量中,这不仅可以使密码等内容不受源代码控制,还可以让您更轻松地更改设置。也许将它们放在 Rakefile 中并为不同的上下文加载不同的环境等。


    要使用环境变量,我执行以下操作:

    # Rakefile
    
    # in this method set up some env vars
    def basic_environment
      # I load them in from a YAML file that is *not* in source control
      # but you could just specify them here
      # e.g. ENV["EMAIL_A"] = "me@example.com"
    end
    
    namespace :app do
    
      desc "Set up the environment locally"
      task :environment do
        warn "Entering :app:environment"
        basic_environment()
      end
    
      desc "Run the app locally"
      task :run_local => "app:environment" do
        exec "bin/rackup config.ru -p 4630"
      end
    end
    
    # from the command line, I'd run
    `bin/rake app:run_local`
    
    # in the Sinatra app file
    configure :production do
        # these are actual settings I use for a Heroku app using Sendgrid
        set "email_options", {      
          :from => ENV["EMAIL_FROM"],
          :via => :smtp,
          :via_options => {
            :address => 'smtp.sendgrid.net',
            :port => '587',
            :domain => 'heroku.com',
            :user_name => ENV['SENDGRID_USERNAME'],
            :password => ENV['SENDGRID_PASSWORD'],
            :authentication => :plain,
            :enable_starttls_auto => true
          },
        }
    end
    
    # then a block with slightly different settings for development
    configure :development do
      # local settings…
        set "email_options", {
          :via => :smtp,
          :via_options => {
            :address              => 'smtp.gmail.com',
            :port                 => '587',
            :enable_starttls_auto => true,
            :user_name            => ENV["EMAIL_A"],
            :password             => ENV["EMAIL_P"], 
            :authentication       => :plain,
            :domain               => "localhost.localdomain"
          }
        }
    end
    

    我通常将这些设置中的大部分保存在本地 YAML 文件中以进行开发,但将这些设置直接添加到生产服务器。有很多方法可以解决这个问题,YMMV。

    【讨论】:

    • 非常感谢,这很棒。我尝试设置 ENV 变量,因为我不想将我的凭据硬编码到邮件配置中,尽管我收到 SMTP 验证错误,尽管当我对凭据进行硬编码时,它的工作原理很奇怪
    • 与 #{params[:name]} 相比,say params[:name] 有什么好处,你在这里使用极化是吗?
    • @Richlewis 我已经用一些关于环境变量的东西更新了答案。 插值,是的,这是大多数字符串处理在 The Ruby Style™ 中完成的方式。对我来说,它读起来更好,我相信它表现更好,但不要依赖那块内存! :)
    猜你喜欢
    • 2012-12-04
    • 1970-01-01
    • 1970-01-01
    • 2016-09-27
    • 2018-01-08
    • 1970-01-01
    • 2018-11-06
    • 1970-01-01
    • 2012-10-07
    相关资源
    最近更新 更多