我有一个包含first_name
和last_name
属性的用户模型。我想编写一个api,用户可以通过first_name
,last_name
或两者来搜索用户。
问题是当用户同时搜索first_name
和last_name
时。我想对结果进行排序,以便完全匹配的记录应该在顶部。与first_name
和last_name
匹配的记录应首先跟随部分匹配的记录。
这是我当前的查询:
q.where('first_name like ? or last_name like ?', "%#{first_name}%", "%#{last_name}%")
答案 0 :(得分:2)
不是SQL方面的专家,所以可能有更好的方法,但可以使用这些数据
User.create([
{ first_name: "Random", last_name: "Last" },
{ first_name: "Random", last_name: "Random" },
{ first_name: "First", last_name: "Random" },
{ first_name: "First", last_name: "Last" },
{ first_name: "Not First", last_name: "Last" },
{ first_name: "First", last_name: "Not Last" },
{ first_name: "Not First", last_name: "Not Last" }
])
当我得到(没有排序)
User.where("first_name like ? or last_name like ?", "%First%", "%Last%").collect { |u| [u.first_name, u.last_name] }
# User Load (0.2ms) SELECT "users".* FROM "users" WHERE (first_name like '%First%' or last_name like '%Last%')
=> [["Random", "Last"], ["First", "Random"], ["First", "Last"], ["Not First", "Last"], ["First", "Not Last"], ["Not First", "Not Last"]]
然后如果我添加.order(User.send(:sanitize_sql, ["first_name like ? and last_name like ? DESC, first_name like ? OR last_name like ? DESC", "%First%", "%Last%", "%First%", "%Last%"])
我就会
User.where("first_name like ? or last_name like ?", "%First%", "%Last%").order(User.send(:sanitize_sql, ["first_name like ? and last_name like ? DESC, first_name like ? OR last_name like ? DESC", "%First%", "%Last%", "%First%", "%Last%"])).collect { |u| [u.first_name, u.last_name] }
# User Load (0.2ms) SELECT "users".* FROM "users" WHERE (first_name like '%First%' or last_name like '%Last%') ORDER BY first_name like '%First%' and last_name like '%Last%' DESC, first_name like '%First%' OR last_name like '%Last%' DESC
=> [["First", "Last"], ["Not First", "Last"], ["First", "Not Last"], ["Not First", "Not Last"], ["Random", "Last"], ["First", "Random"]]
在这些事情上更像是专家的人可能会知道一种更好的方法,但这看起来就像是要完成它。