From 44be82dd18c372862c2421a1934ff816f7cccd97 Mon Sep 17 00:00:00 2001 From: Yorick Peterse Date: Fri, 6 Oct 2017 16:50:54 +0200 Subject: Refactor User.find_by_any_email By using SQL::Union we can return a proper ActiveRecord::Relation, making it possible to select the columns we're interested in (instead of all of them). --- app/models/user.rb | 18 +++++++++--------- spec/models/user_spec.rb | 13 +++++++++++++ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index aa88cda4dc0..8205c3e29b9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -269,16 +269,16 @@ class User < ActiveRecord::Base # Find a User by their primary email or any associated secondary email def find_by_any_email(email) - sql = 'SELECT * - FROM users - WHERE id IN ( - SELECT id FROM users WHERE email = :email - UNION - SELECT emails.user_id FROM emails WHERE email = :email - ) - LIMIT 1;' + by_any_email(email).take + end + + # Returns a relation containing all the users for the given Email address + def by_any_email(email) + users = where(email: email) + emails = joins(:emails).where(emails: { email: email }) + union = Gitlab::SQL::Union.new([users, emails]) - User.find_by_sql([sql, { email: email }]).first + from("(#{union.to_sql}) #{table_name}") end def filter(filter_name) diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d2f97009ad9..a3ebf649aa8 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -841,6 +841,19 @@ describe User do end end + describe '.by_any_email' do + it 'returns an ActiveRecord::Relation' do + expect(described_class.by_any_email('foo@example.com')) + .to be_a_kind_of(ActiveRecord::Relation) + end + + it 'returns a relation of users' do + user = create(:user) + + expect(described_class.by_any_email(user.email)).to eq([user]) + end + end + describe '.search' do let!(:user) { create(:user, name: 'user', username: 'usern', email: 'email@gmail.com') } let!(:user2) { create(:user, name: 'user name', username: 'username', email: 'someemail@gmail.com') } -- cgit v1.2.1