Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql Rails 4 ActiveRecord查询:在order子句中绑定变量_Mysql_Ruby On Rails 4_Rails Activerecord - Fatal编程技术网

Mysql Rails 4 ActiveRecord查询:在order子句中绑定变量

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

我试图在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\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,后面是其他所有内容。好的,我直到现在才知道。谢谢你的提示。