2个表单在同一页面上,使用Sinatra中的Pony发送,相同的电子邮件地址

时间:2013-02-07 11:46:01

标签: ruby forms sinatra pony

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

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

到目前为止,我想出了什么,但未定义的方法是

 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

这是否可能,或者每种形式都必须单独处理?

由于

1 个答案:

答案 0 :(得分:3)

我将通过几个阶段来重构此代码。

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 vars中,这样不仅可以保存密码等源代码,还可以让您更轻松地更改设置。也许将它们放在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。