I am trying to use the following sql statement in a Rails application with Rails query helper methods. The result of this sql in the original (non-Rails) application is to do a fuzzy search on someone’s name with any letter. For example, if you enter an “a” in the search box, it will return everyone name that has the letter “a” in it somewhere. “Marissa Jones” and “Andrea Barfs” would both be matches.
"select e.id, e.firstName, e.lastName, e.title " .
"from employee e left join employee r on r.managerId = e.id " .
"WHERE UPPER(CONCAT(e.firstName, ' ', e.lastName)) LIKE :name " .
"group by e.id order by e.lastName, e.firstName";
I tried to translate that sql statement using some of Rails active record query interface helper methods. (I didn’t attempt to include the ‘join’ from the above sql because it didn’t seem necessary for the fuzzy search or for the purposes of my app). There is one user supplied parameter :query
employees_controller.rb
respond_to :json
...
def getEmployeesByName
query = Employee.select("id, firstname, lastname, title")
q = "%#{params[:query]}%"
query.where("UPPER(CONCAT(firstName, ' ', lastName)) LIKE ?", q).to_sql
query.group("id")
query.order("lastname", "firstname")
respond_with query.all
end
When I try my code, it’s returning all of the 5 employees in the database, even if they don’t have the letter “a” in their name. This is the sql shown in the server, when, for example, I enter an “a” in the search box.
Processing by EmployeesController#getEmployeesByName as JSON
Parameters: {"query"=>"a"}
Employee Load (0.1ms) SELECT id, firstname, lastname, title FROM "employees"
So it seems the last four lines of my action are being ignored
query.where("UPPER(CONCAT(firstName, ' ', lastName)) LIKE ?", q).to_sql
query.group("id")
query.order("lastname", "firstname")
respond_with query.all
Can anyone explain what I’m doing wrong. Thank you in advance.
queryis being assigned an instance ofEmployeeby the first line. You are then callingwhere,group, andorderon the classEmployeevia the instance, but ignoring the result in every case. Finally, you are callingEmployee.allvia the instance, and inspecting the result, which correctly includes all records.Try something like: