Commit 199425ce authored by Tiago Botelho's avatar Tiago Botelho

Inserts exact matches of username, email and name to the top of the user search list

parent 4f620eb9
...@@ -299,11 +299,20 @@ class User < ActiveRecord::Base ...@@ -299,11 +299,20 @@ class User < ActiveRecord::Base
table = arel_table table = arel_table
pattern = "%#{query}%" pattern = "%#{query}%"
order = <<~SQL
CASE
WHEN users.name = %{query} THEN 0
WHEN users.username = %{query} THEN 1
WHEN users.email = %{query} THEN 2
ELSE 3
END
SQL
where( where(
table[:name].matches(pattern) table[:name].matches(pattern)
.or(table[:email].matches(pattern)) .or(table[:email].matches(pattern))
.or(table[:username].matches(pattern)) .or(table[:username].matches(pattern))
) ).reorder(order % { query: ActiveRecord::Base.connection.quote(query) }, id: :desc)
end end
# searches user by given pattern # searches user by given pattern
......
---
title: Inserts exact matches of name, username and email to the top of the search
list
merge_request: 12525
author:
...@@ -754,42 +754,49 @@ describe User, models: true do ...@@ -754,42 +754,49 @@ describe User, models: true do
end end
describe '.search' do describe '.search' do
let(:user) { create(:user) } 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') }
it 'returns users with a matching name' do describe 'name matching' do
expect(described_class.search(user.name)).to eq([user]) it 'returns users with a matching name with exact match first' do
end expect(described_class.search(user.name)).to eq([user, user2])
end
it 'returns users with a partially matching name' do it 'returns users with a partially matching name' do
expect(described_class.search(user.name[0..2])).to eq([user]) expect(described_class.search(user.name[0..2])).to eq([user2, user])
end end
it 'returns users with a matching name regardless of the casing' do it 'returns users with a matching name regardless of the casing' do
expect(described_class.search(user.name.upcase)).to eq([user]) expect(described_class.search(user2.name.upcase)).to eq([user2])
end
end end
it 'returns users with a matching Email' do describe 'email matching' do
expect(described_class.search(user.email)).to eq([user]) it 'returns users with a matching Email' do
end expect(described_class.search(user.email)).to eq([user, user2])
end
it 'returns users with a partially matching Email' do it 'returns users with a partially matching Email' do
expect(described_class.search(user.email[0..2])).to eq([user]) expect(described_class.search(user.email[0..2])).to eq([user2, user])
end end
it 'returns users with a matching Email regardless of the casing' do it 'returns users with a matching Email regardless of the casing' do
expect(described_class.search(user.email.upcase)).to eq([user]) expect(described_class.search(user2.email.upcase)).to eq([user2])
end
end end
it 'returns users with a matching username' do describe 'username matching' do
expect(described_class.search(user.username)).to eq([user]) it 'returns users with a matching username' do
end expect(described_class.search(user.username)).to eq([user, user2])
end
it 'returns users with a partially matching username' do it 'returns users with a partially matching username' do
expect(described_class.search(user.username[0..2])).to eq([user]) expect(described_class.search(user.username[0..2])).to eq([user2, user])
end end
it 'returns users with a matching username regardless of the casing' do it 'returns users with a matching username regardless of the casing' do
expect(described_class.search(user.username.upcase)).to eq([user]) expect(described_class.search(user2.username.upcase)).to eq([user2])
end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment