【问题标题】:Ruby on Rails: Validate contact form without modelRuby on Rails:验证没有模型的联系表单
【发布时间】:2019-10-26 15:55:06
【问题描述】:

我有一个简单的联系表单,它接受以下字段(都应该是必需的):姓名、电子邮件、电话和消息。

我还想验证电子邮件地址。

应向用户提供有关表单提交是否成功或是否有错误的响应。

如果是,请在视图上显示特定错误。

此表单未连接到任何数据库模型。我不保存提交。只能邮寄。

我的 PagesController 中有一个 POST 路由设置为 contact_form

在我的 PagesController 我有

    def contact_form
        UserMailer.contact_form(contact_form_params).deliver
    end

在我的 UserMailer 类中,我有:

 def contact_form(params)
      @formParams = params;
      @date = Time.now
         mail(
            to: "support@example.com",
            subject: 'New Contact Form Submission', 
            from: @formParams[:email],
            reply_to: @formParams[:email],
        )
    end

这封邮件成功,但没有验证。如果验证通过,我只需要运行邮件块。然后向用户返回响应。

由于我没有模型,我不知道该怎么做。我看到的所有答案都告诉人们在 ActiveRecord 模型上使用validates

只有几个答案:

(注意我已经更新了我的参数)

class UserMailerForm
  include ActiveModel::Validations

  def initialize(options)
    options.each_pair{|k,v|
      self.send(:"#{k}=", v) if respond_to?(:"#{k}=")
    }
  end
  attr_accessor :first_name, :last_name, :email, :phone, :message

  validates :first_name, :last_name, :email, :phone, :message, presence: true
  validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } 
end
 def contact_form
    @form = UserMailerForm.new(contact_form_params)

    if @form.valid?
      UserMailer.contact_form(contact_form_params).deliver
    else
     logger.debug('invalid')
     logger.debug(@form.valid?)
    end

  end

这会在有效时发送邮件。但是,我仍然不确定是否要向用户发送信息

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    您可以make UserMailer a modeluse validations on that

    class UserMailer
      include ActiveModel::Model       # make it a model
      include ActiveModel::Validations # add validations
    
      attr_accessor :name, :email, :phone, :message
    
      validates :name, :email, :phone, :message, presence: true
      validates :email, format: { with: URI::MailTo::EMAIL_REGEXP } 
    
      def send_mail(subject:, to:)
        mail(
          to: to,
          subject: subject, 
          from: email,
          reply_to: email,
        )
      end
    end
    

    然后像使用任何其他模型一样使用它。

    def UserMailersController < ApplicationController
      def new
        @user_mailer = UserMailer.new
      end
    
      def create
        @user_mailer = UserMailer.new(params)
        if @user_mailer.valid?
          @user_mailer.send_mail(
            to: "support@example.com",
            subject: 'New Contact Form Submission',
          )
        else
          # Use @user_mailer.errors to inform the user of their mistake.
          render 'new'
        end
      end
    end
    

    如果您有多个与 UserMailer 关联的表单,您可以创建单独的类来验证每个表单的输入,然后将它们传递给 UserMailer。无论如何,您可能仍希望在 UserMailer 上进行验证。

    【讨论】:

    • 谢谢!在我尝试实现之前的快速问题 - 这个类文件应该放在哪里?
    • 我遇到了一个问题:wrong number of arguments (given 1, expected 0; required keywords: first_name, last_name, email, phone, message) 我更改了一些参数,但它们都在 UserMailerForm 中
    • @millman2394 我会把它和UserMailer 放在一起,可能是app/servicesapp/lib。您可以将其设为UserMailer::Form 并将其放入app/services/user_mailer/form.rb。至于你的错误,我需要看看你是怎么打电话给UserMailerForm.new的。
    • @millman2394 请参阅guides.rubyonrails.org/… 重要的是您将无效的@form 对象发送回您的new 模板并使用@form.errors 向用户显示错误。这是一个粗略的草图:gist.github.com/schwern/2cea64177f255d423cbb316de96e7bb7simple_form 这样的 gem 可以让这变得不那么乏味,但是学习手动做几次还是不错的。
    • 如果你使用的是 Rails 5,你真的应该使用 ActiveModel::Attributes 而不是 attr_accessor。
    【解决方案2】:

    您可以在 PORO 上使用 ActiveModel::Validations,就像 AR 一样。

    
    class MyFormObject
      include ActiveModel::Validations
    
      def initialize(options)
        options.each_pair{|k,v|
          self.send(:"#{k}=", v) if respond_to?(:"#{k}=")
        }
      end
    
      attr_accessor :name, :email, :phone, :message
    
      validates :name, presence: true
      # and so on...
    
    end
    

    【讨论】:

    • 我是 ruby​​ 和 ruby​​ on rails 的新手。你能解释一下你的代码在做什么吗?你的看起来比其他答案更复杂
    • @millman2394 使用"${k}" 而不是"#{k}" 存在一个小错误。它基本上和我的一样,但是是动态的。它将您传入的每一对传递给new 并调用self.key = value,但前提是对象具有访问器。这使它的行为类似于其他 Rails 模型。
    猜你喜欢
    • 2011-07-20
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    • 2019-04-08
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多