Mysql Rails 4 ActiveRecord查询:在order子句中绑定变量
我试图在mysql查询中内置一个动态顺序,以便将某些匹配项的优先级设置在顶部Mysql Rails 4 ActiveRecord查询:在order子句中绑定变量,mysql,ruby-on-rails-4,rails-activerecord,Mysql,Ruby On Rails 4,Rails Activerecord,我试图在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[:se
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\u 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\u order\u参数中得到一个错误,该参数表示方向应该是:asc或:desc
除了手动清理搜索,然后将其直接插入到顺序字符串中之外,有没有办法让它像where子句的bind变量一样工作?所以经过一些挖掘,我认为我找到了解决方法,尽管我希望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假定参数[: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]}%"
)
您的“订购人”部分不正确。“订单依据”不能包含等号!将search_值放入“orderby”部分是没有意义的。请参阅MySQL引用:这绝对不正确,等于将返回1或0。因此,根据搜索的评估方式,最终结果在每个记录的基础上执行为“ORDER BY 1 DESC,0 DESC,1 DESC,0 DESC”。只需尝试执行“按10=id DESC从任意顺序中选择*”,它将在顶部返回id 10,后面是其他所有内容。好的,我直到现在才知道。谢谢你的提示。