0

I have two registration forms: one that can register with any email address and the other with just one specific domain. How to allow that from the User.rb model?

Something like this may work:

validates_format_of :email, :with => /.io/

But because I have two registration forms and the url for that form has an id of 2:

validates_format_of :email, :with => /.io/ if params[id] == 2

I do understand that params is not available in the model but based on what I want to achieve, how to accomplish this?

Basically form with id = 1 can register with any email. Form with id = 2 can only register with a .io email address (domain).

2 Answers 2

1

This sounds like a good use for validation contexts. A validates* method can accept an :on option, which is the name of the "context" in which the validation will be triggered; for example:

validates_format_of :email, :with => /\.io\z/, on: :restricted_email

This validation will only be triggered if the option context: :restricted_email is passed to the save or save! method. Here's how you might use it in your controller:

def create
  @user = User.new(params[:user])

  if params[:id] == 2
    @user.save!(context: :restricted_email)
  else
    @user.save!
  end
end

Here's a good blog post on the topic: http://blog.arkency.com/2014/04/mastering-rails-validations-contexts/

Sign up to request clarification or add additional context in comments.

4 Comments

Error: The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?
Jordon, one last question. With your code, how easily to add more domain to the regex?
It's pretty easy to express domain names in a regular expression, e.g. /\.(com|edu|io|co\.uk)\z/.
An easy way to play around with regular expressions in Ruby is Rubular.com: rubular.com/r/QNgfdyo9sH
1

You could add an attribute to the model that would indicate which form registration was coming from, like :registered_io, sent to your model through a hidden field in the form

#...
<%= f.hidden_field :registered_io, value="true" # or false %> 

Then in your model you could just do an

validates :format_of_io_email_should if self.registered_io 
validates :format_of_universal_email_should if !self.registered_io

def format_of_io_email_should
 # regex ahoy or whatever
end
def format_of_universal_email_should
# same same but different
end

Don't forget to run your migrations to store the attribute, too!

$ rails migration add_column_registered_io_to_user registered_io:boolean 

Also don't forget to allow :registered_io in the strong params in the controller.

3 Comments

This is the better option, in my opinion. Whatever criteria you have for restricting a user to .io email addresses, you are probably going to want to maintain that context after the user is created. Otherwise you have no way of knowing whether an existing user with a .io email address belonged to the given group or not.
I'm getting undefined method for registered_to from the model.
registered_to or registered_io? Head in to $ rails console to check it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.