ermolushka ermolushka - 4 months ago 42
Ruby Question

How to validate email on backend (Rails) and allow not to fill this field in the form?

I'm working on a simple one-page contact form. Contact model have two attributes: phone and email. Email should be validated on backend (i did it in my model). But user can fill either email or phone in the contact form and send it. No Email field in necessary and i don't know how to make it optional.

contact.rb

class Contact < MailForm::Base
attribute :phone
attribute :email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i,
presence: false

def headers
{
:subject => "My Contact Form",
:to => "email@admin.com",
:from => %("#{phone}" <#{email}>)
}
end


end

contacts_controller.rb

class ContactsController < ApplicationController

def new
@contact = Contact.new
end

def create
@contact = Contact.new(contact_params)
@contact.request = request
if @contact.deliver
flash.now[:notice] = 'Ваша заявка принята!'
render :new
else
flash.now[:notice] = 'Введите корректный email.'
render :new
end
end

private

def contact_params
params.require(:contact).permit(:phone, :email)
end
end


new.html.erb

<%= simple_form_for @contact, html: {class: 'form-inline'} do |f| %>
<div class="form-group">
<div class="col-sm-6">
<%= f.input_field :email, class: "form-control", placeholder: "email", required: false %>
</div>
</div>
<div class="form-group">
<div class="col-sm-6">
<%= f.input_field :phone, class: "form-control", placeholder: "+7 (095) 123-45-67" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-6">
<%= f.button :submit, 'Submit', :class=> "btn btn-success" %>
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<% flash.each do |key, value| %>
<div class="alert alert-info" role="alert">
<div class="alert alert-<%= key %>"><%= value %></div>
</div>
<% end %>
</div>
</div>
<% end %>

Answer

I'd probably go about it this way:

class Contact < MailForm::Base
  attribute :phone
  attribute :email,     :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i, 
                      presence: false, allow_blank: true
  validate :at_least_a_contact

  def headers
    {
      :subject => "My Contact Form",
      :to => "email@admin.com",
      :from => %("#{phone}" <#{email}>)
    }
  end
  private
    def at_least_a_contact
      unless phone.present? || email.present?
        errors.add(:contact, "You need at least a contact method")
      end
    end
end