Spec and refactor User.find_for_commit
Now it executes a single query instead of a possible three at the cost of some scary-looking ARel calls.
This commit is contained in:
parent
2efb0b6e93
commit
7e31a369f5
2 changed files with 45 additions and 4 deletions
|
@ -220,10 +220,26 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_for_commit(email, name)
|
def find_for_commit(email, name)
|
||||||
# Prefer email match over name match
|
user_table = arel_table
|
||||||
User.where(email: email).first ||
|
email_table = Email.arel_table
|
||||||
User.joins(:emails).where(emails: { email: email }).first ||
|
|
||||||
User.where(name: name).first
|
# Use ARel to build a query:
|
||||||
|
query = user_table.
|
||||||
|
# SELECT "users".* FROM "users"
|
||||||
|
project(user_table[Arel.star]).
|
||||||
|
# LEFT OUTER JOIN "emails"
|
||||||
|
join(email_table, Arel::Nodes::OuterJoin).
|
||||||
|
# ON "users"."id" = "emails"."user_id"
|
||||||
|
on(user_table[:id].eq(email_table[:user_id])).
|
||||||
|
# WHERE ("user"."email" = '<email>' OR "user"."name" = '<name>')
|
||||||
|
# OR "emails"."email" = '<email>'
|
||||||
|
where(
|
||||||
|
user_table[:email].eq(email).
|
||||||
|
or(user_table[:name].eq(name)).
|
||||||
|
or(email_table[:email].eq(email))
|
||||||
|
)
|
||||||
|
|
||||||
|
find_by_sql(query.to_sql).first
|
||||||
end
|
end
|
||||||
|
|
||||||
def filter(filter_name)
|
def filter(filter_name)
|
||||||
|
|
|
@ -340,6 +340,31 @@ describe User do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.find_for_commit' do
|
||||||
|
it 'finds by primary email' do
|
||||||
|
user = create(:user, email: 'foo@example.com')
|
||||||
|
|
||||||
|
expect(User.find_for_commit(user.email, '')).to eq user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds by secondary email' do
|
||||||
|
email = create(:email, email: 'foo@example.com')
|
||||||
|
user = email.user
|
||||||
|
|
||||||
|
expect(User.find_for_commit(email.email, '')).to eq user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'finds by name' do
|
||||||
|
user = create(:user, name: 'Joey JoJo')
|
||||||
|
|
||||||
|
expect(User.find_for_commit('', 'Joey JoJo')).to eq user
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns nil when nothing found' do
|
||||||
|
expect(User.find_for_commit('', '')).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'search' do
|
describe 'search' do
|
||||||
let(:user1) { create(:user, username: 'James', email: 'james@testing.com') }
|
let(:user1) { create(:user, username: 'James', email: 'james@testing.com') }
|
||||||
let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') }
|
let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') }
|
||||||
|
|
Loading…
Reference in a new issue