【问题标题】:Ruby on Rails query more than one fieldsRuby on Rails 查询多个字段
【发布时间】:2016-07-04 20:59:01
【问题描述】:

在我的 rails 应用程序中,如何从我的数据库中查询多个字段?目前用户根据关键字搜索产品时,查询只从db中获取name字段:

@products = @products.where("lower(name) LIKE ?", "%#{params[:search_free_text].downcase}%")

我需要将descriptionhighlight 都以文本格式包含在查询中。谢谢!!

【问题讨论】:

    标签: ruby-on-rails ruby postgresql


    【解决方案1】:

    您只需要遵循SQL 格式即可:

    @products = @products.where("lower(name) LIKE :query OR description LIKE :query", query: "%#{params[:search_free_text].downcase}%")
    

    【讨论】:

    • 嗨,params[:description_text] 是干什么用的?
    • 这只是我的一个假设。您需要将params 传递给您从视图中收到的description
    • @Deep:您不应该通过字符串插值来构建 SQL 查询。这是不安全的,可用于SQL injection 攻击。始终使用 Rails 的 where('... LIKE ...')an array or a hash
    • @spickermann 哦,好吧,我在项目的某些地方也使用过它,但是在模型中而不是在控制器中,所以在没有用户参数的情况下在模型中使用可以吗?
    • 当您绝对确定它永远不会与用户输入一起使用时,那可能没问题。但我建议始终使用哈希和数组语法来确保 Rails 正确引用查询。不使用此安全功能没有任何好处。
    【解决方案2】:

    试试这个 以某种方式在模型Product中创建一个范围@

     class Product < ActiveRecord::Base
      scope :search_ndh, -> (name_text, desc_text, highlight_text){where("lower(name) LIKE :name OR description LIKE :desc OR highlight LIKE :high", name: "%#{name_text.downcase}%", desc: "%#{desc_text}%", high: "%#{highlight_text}%")} 
     end
    

    现在使用范围

    @products.search_ndh(params[:search_free_text].downcase, params[:search_description_text], params[:search_highlight_text])
    

    或其他方式

      products = Product.arel_table
      Product.where(products[:name].matches("%#{params[:search_free_text]}%").or(products[:description].matches("%#{params[:search_description_text]}%")).or(products[:highlight].matches("%#{params[:search_highlight_text]}%")))
    

    或在动态字段范围内

    class Product < ActiveRecord::Base
      SEARCH_COLUMNS = [:name, :description, :highlight]
      scope :search, lambda{ |q| where(SEARCH_COLUMNS.map{|c| self.arel_table[c].matches("%#{q}%").to_sql}.join(' OR '))} 
    end
    

    然后

     Product.search(params[:search_text])
    

    它会生成

    Product.search("das")
    
    SELECT "products".* FROM "products" WHERE ("products"."name" LIKE '%das%' OR "products"."description" LIKE '%das%' OR "products"."highlight" LIKE '%das%')
    

    【讨论】:

      【解决方案3】:

      这可以通过这样的 SQL 来完成:

      @products = @products.where(
        %w( name description highlight ).map { |column_name| 
          "lower(#{column_name}) LIKE :query" 
        }.join(' OR '),
        query: "%#{params[:search_free_text].downcase}%")
      

      我会说使用范围是值得的:

      # in your app/models/product.rb
      FULLTEXT_COLUMNS = %w( name description highlight )
      scope :search, lambda { |query| 
        where(
          FULLTEXT_COLUMNS.map { |c| "lower(#{c}) LIKE :query" }.join(' OR '),
          query: "%#{query.downcase}%"
        )
      }
      
      # in your controller:
      @products = @products.search(params[:search_free_text])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-16
        • 2019-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-21
        相关资源
        最近更新 更多