diff options
-rw-r--r-- | app/models/principal.rb | 17 | ||||
-rw-r--r-- | test/unit/principal_test.rb | 10 |
2 files changed, 21 insertions, 6 deletions
diff --git a/app/models/principal.rb b/app/models/principal.rb index e4410dde2..b2476c154 100644 --- a/app/models/principal.rb +++ b/app/models/principal.rb @@ -69,15 +69,20 @@ class Principal < ActiveRecord::Base where({}) else pattern = "%#{q}%" - sql = %w(login firstname lastname).map {|column| "LOWER(#{table_name}.#{column}) LIKE LOWER(:p)"}.join(" OR ") + sql = "LOWER(#{table_name}.login) LIKE LOWER(:p)" sql << " OR #{table_name}.id IN (SELECT user_id FROM #{EmailAddress.table_name} WHERE LOWER(address) LIKE LOWER(:p))" params = {:p => pattern} - if q =~ /^(.+)\s+(.+)$/ - a, b = "#{$1}%", "#{$2}%" - sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:a) AND LOWER(#{table_name}.lastname) LIKE LOWER(:b))" - sql << " OR (LOWER(#{table_name}.firstname) LIKE LOWER(:b) AND LOWER(#{table_name}.lastname) LIKE LOWER(:a))" - params.merge!(:a => a, :b => b) + + tokens = q.split(/\s+/).reject(&:blank?).map { |token| "%#{token}%" } + if tokens.present? + sql << ' OR (' + sql << tokens.map.with_index do |token, index| + params.merge!(:"token_#{index}" => token) + "(LOWER(#{table_name}.firstname) LIKE LOWER(:token_#{index}) OR LOWER(#{table_name}.lastname) LIKE LOWER(:token_#{index}))" + end.join(' AND ') + sql << ')' end + where(sql, params) end } diff --git a/test/unit/principal_test.rb b/test/unit/principal_test.rb index 2abd110f9..bb03a088e 100644 --- a/test/unit/principal_test.rb +++ b/test/unit/principal_test.rb @@ -127,6 +127,16 @@ class PrincipalTest < ActiveSupport::TestCase assert_equal User.find(2), results.first end + test "like scope should find lastname with spaces" do + user = User.find(1) + user.update_columns(:firstname => 'Leonardo', :lastname => 'da Vinci') + + results = Principal.like('Leonardo da Vinci') + + assert_equal 1, results.count + assert_equal user, results.first + end + def test_like_scope_with_cyrillic_name user = User.generate!(:firstname => 'Соболев', :lastname => 'Денис') results = Principal.like('Собо') |