From 03efccad296d8aad34a7f9826664f5883854b61c Mon Sep 17 00:00:00 2001 From: RafaFP Date: Fri, 4 Nov 2016 20:11:14 +0000 Subject: [PATCH 1/2] The search in manage/users now orders by ammount of matches before name TODO: spec --- app/models/user.rb | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 0c3b6459e..f3eab6c5f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -86,22 +86,26 @@ def self.find_first_by_auth_conditions(warden_conditions) default_scope { where(disabled: false) } scope :search_by_terms, -> (words, include_private=false) { - query = joins(:profile).includes(:profile).order("profiles.full_name") - - words ||= [] - words = [words] unless words.is_a?(Array) - query_strs = [] - query_params = [] - - words.each do |word| - str = "profiles.full_name LIKE ? OR users.username LIKE ?" - str += " OR users.email LIKE ?" if include_private - query_strs << str - query_params += ["%#{word}%", "%#{word}%"] - query_params += ["%#{word}%"] if include_private + query = joins(:profile).includes(:profile) + puts words.inspect + if words.present? + words ||= [] + words = [words] unless words.is_a?(Array) + query_strs = [] + query_params = [] + query_orders = [] + + words.each do |word| + str = "profiles.full_name LIKE ? OR users.username LIKE ?" + str += " OR users.email LIKE ?" if include_private + query_strs << str + query_params += ["%#{word}%", "%#{word}%"] + query_params += ["%#{word}%"] if include_private + query_orders += ["CASE WHEN profiles.full_name LIKE '%#{word}%' THEN 1 ELSE 0 END + CASE WHEN users.username LIKE '%#{word}%' THEN 1 ELSE 0 END + CASE WHEN users.email LIKE '%#{word}%' THEN 1 ELSE 0 END"] + end + query = query.where(query_strs.join(' OR '), *query_params.flatten).order(query_orders.join(' + ') + " DESC") end - - query.where(query_strs.join(' OR '), *query_params.flatten) + query.order("profiles.full_name") } alias_attribute :name, :full_name From e0938ef25f062c3b09b13fd665c00874e4eb7a20 Mon Sep 17 00:00:00 2001 From: RafaFP Date: Mon, 7 Nov 2016 17:40:17 +0000 Subject: [PATCH 2/2] Added spec to test that the manager will get the users ordered by amount of search matches --- app/models/user.rb | 2 +- spec/controllers/manage_controller_spec.rb | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index f3eab6c5f..d31be5ca2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -87,7 +87,7 @@ def self.find_first_by_auth_conditions(warden_conditions) scope :search_by_terms, -> (words, include_private=false) { query = joins(:profile).includes(:profile) - puts words.inspect + if words.present? words ||= [] words = [words] unless words.is_a?(Array) diff --git a/spec/controllers/manage_controller_spec.rb b/spec/controllers/manage_controller_spec.rb index 3acee7d7d..d7a3aab5d 100644 --- a/spec/controllers/manage_controller_spec.rb +++ b/spec/controllers/manage_controller_spec.rb @@ -82,6 +82,21 @@ it { assigns(:users)[3].should eql(@u1) } end + context "on a search_by_terms orders @users by more hits" do + before { + @u1 = FactoryGirl.create(:user, :_full_name => 'First user created') + @u2 = user + @u2.profile.update_attributes(:full_name => 'Second user created') + @u3 = FactoryGirl.create(:user, :_full_name => 'A user starting with letter A') + @u4 = FactoryGirl.create(:user, :_full_name => 'Being someone starting with B') + } + before(:each) { get :users, :q => 'second user' } + it { assigns(:users).count.should be(3) } + it ("On top the user with 2 matches") { assigns(:users)[0].should eql(@u2) } + it ("Then another user with 1 match and has higher alphabetical order") { assigns(:users)[1].should eql(@u3) } + it ("Then another user with 1 match and has lower alphabetical order") { assigns(:users)[2].should eql(@u1) } + end + context "paginates the list of users" do before { 45.times { FactoryGirl.create(:user) }