1

The parameter email_or_phone_number comes from a client side and I need this for an authentication. However, the model has email and phone number fields separately.

What is the right way to parse the email_or_phone_number attribute, so then I could use find_by to find a user?

find_by(email: email, phone_number: phone_number)

If it's number, then it should become phone_number, but if it's not, then that is supposed to be an email.

Billy Logan
  • 2,470
  • 6
  • 27
  • 45

3 Answers3

4

A simple readable solution for your question would be using an OR query

Mongoid

User.where(email: params[:email_or_phone_number])
    .or(phone_number: params[:email_or_phone_number])
    .first

UPDATE Active Record

User.where(email: params[:email_or_phone_number])
    .or(User.where(phone_number: params[:email_or_phone_number]))

The other method could be using a Regex for identifying Email Format or Phone Number Format of the value in params[:email_or_phone_number] but I have not come across any which are full proof in case of identifying there formats.

Community
  • 1
  • 1
1

You can split email or number with a regex.

 x = {email_or_phone_number:"3333"}
 x[:email_or_phone_number].match(/^\d+/)

if x is nil, then

 x[:email_or_phone_number].match(/\A([\w+\-]\.?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i)

else: is not valid input! Save result and pass res to find_by

sirion1987
  • 111
  • 4
  • 13
1

Assuming that the desired behavior is that searching for 123 matches both greg123@example.com (an email) and 123123123 (a phone number) then the correct query would be:

User.where('email ILIKE :q OR phone ILIKE :q',
           q: "%#{params[:email_or_phone]}%")

I'm not sure what your database is but keep in mind that this query may perform poorly on larger datasets. If that's the case I recommend you take a look at pg_trgm (Postgres-only) or full-text search solutions.

Greg Navis
  • 2,818
  • 10
  • 10