简体   繁体   中英

Ruby on Rails: Validate contact form without model

I have a simple contact form that accepts the following fields (all should be required): Name, Email, phone, and message.

I also want to validate the email address.

Users should be given a response on whether or not the form submitted successfully, or if there are errors.

if so, display specific errors on the view.

This form is not connected to any database model. I'm not saving submissions. Only mailing.

I have a POST route set to contact_form in my PagesController

In my PagesController I have

    def contact_form
        UserMailer.contact_form(contact_form_params).deliver
    end

In my UserMailer class I have:

 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

This mails successfully, but there's no validation. I need to only run the mail block if validation passes. then return a response to the user.

Since I have no Model, I'm not sure how to do this. All the answers I see tell people to use validates on the ActiveRecord model.

With the few answers:

(note I've updated my params)

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

This sends mail when valid. However, I'm still unsure about sending info to the user

You can make UserMailer a model and use 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

Then use it like any other model.

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

If you have multiple forms associated with UserMailer, you can make separate classes to validate each Form's inputs and then pass them along to UserMailer. You'd likely still want validations on UserMailer regardless.

You can use ActiveModel::Validations on your PORO the same way AR does this.


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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM