Say the users of my app are admins of email domains and each of them is allowed to create mailboxes for one or multiple domains by typing out the email address for that mailbox.
Currently, the Mailbox
-model has an unpersisted attribute that acts as a whitelist for domains.
Is there an alternative/better way to implement something like this? I most likely want to implement this as a model validation to display a nice message to the user. I do not want to discard invalid email
attributes nor do I want to have a view-only solution (something like using a <select>
for the domain).
class Mailbox < ApplicationRecord
attribute :_allowed_domains, array: true
validates :email, presence: true, format: URI::MailTo::EMAIL_REGEXP
validate :email_domain_allowed, if: :email
private
def email_domain_allowed
raise "_allowed_domains is not populated, cannot validate" if self._allowed_domains.nil?
self.errors.add(:email, :domain_not_allowed) if self._allowed_domains.exclude?(self.email.split("@", 2).last)
end
end
class MailboxesController < ApplicationController
def create
@mailbox = Mailbox.new(mailbox_params)
respond_to do |format|
if @mailbox.save
format.html { redirect_to(@mailbox) }
format.json { head(:created) }
else
format.html { render("new", status: :unprocessable_content) }
format.json { render(json: { error: @mailbox.errors.full_messages.to_sentence }, status: :unprocessable_content) }
end
end
end
private
def mailbox_params
parameters = params.expect(mailbox: [:email])
parameters[:_allowed_domains] = current_login.user.allowed_domains
return parameters
end
end