我试图在我的mysql查询中内置动态订单,以便在顶部优先处理某些匹配。
Ticket.where(
"id LIKE :search || name LIKE :search",
{search: "%#{params[:search]}]%"}
).order(
"id = :exact DESC, name = :exact DESC, id LIKE :search DESC, name LIKE :search DESC",
{exact: params[:search], search: "%#{params[:search]}%"}
)
查询应该像这样假设params [:search] =' search_value':
SELECT * FROM tickets
WHERE id LIKE "%search_value%" || name LIKE "%search_value%"
ORDER BY id = 'search_value' DESC, name = 'search_value' DESC, id LIKE "%search_value%" DESC, name LIKE "%search_value%" DESC;
我随时都这样做但是从ActiveRecord :: QueryMethods.validate_order_args收到错误,说明Direction应该是:asc或:desc。
除了手动清理搜索然后将其直接插入到顺序字符串中之外,有没有办法让它像where子句的绑定变量一样运行?
答案 0 :(得分:0)
所以经过一番挖掘后我觉得我已经找到了解决方案,虽然我希望rails有更好的方法。
我已将其包含在我的rails项目中
class ActiveRecord::Base
def self.corder *array
statement = array.shift
while (i=array.shift).present?
case i
when Hash
i.each do |k,v|
statement.gsub!(':' + k.to_s, ActiveRecord::Base.sanitize(v))
end
when String
statement.sub!('?', ActiveRecord::Base.sanitize(i))
else
raise "Unknown type: #{i} -- #{i.class}"
end
end
self.order(statement)
end
def corder *array
statement = array.shift
while (i=array.shift).present?
case i
when Hash
i.each do |k,v|
statement.gsub!(':' + k.to_s, sanitize(v))
end
when String
statement.sub!('?', sanitize(i))
else
raise "Unknown type: #{i} -- #{i.class}"
end
end
self.order!(statement)
end
end
就我的目的而言,虽然可以很容易地扩展,但这种方法很有效。这两个是完全相同的(在类和实例上需要它的简单解决方案)。
此时你可以:
Model.where(
'id LIKE :search || name LIKE :search',
{search: "%#{params[:search]}%"}
).order(
'id = :exact DESC, name = :exact DESC, id LIKE :rough DESC, name LIKE :rough DESC',
{exact: params[:search], rough: "%#{params[:search]}%"}
)
SQL假设params [:search] ==' ibm':
SELECT * FROM model WHERE id LIKE '%ibm%' || name LIKE '%ibm%' ORDER BY id = 'ibm' DESC, name = 'ibm' DESC, id LIKE '%ibm%' DESC, name LIKE '%ibm%' DESC;
或者'?'绑定变量也起作用,例如:
Model.where(
'id LIKE ? || name LIKE ?',
"%#{params[:search]}%", "%#{params[:search]}%"
).order(
'id = ? DESC, name = ? DESC, id LIKE ? DESC, name LIKE ? DESC',
params[:search], params[:search], "%#{params[:search]}%", "%#{params[:search]}%"
)