Rails 4 在"Where"方法中安全地使用变量



我已经自己搜索了Rails 4应用程序。现在我需要为用户提供不同的列进行搜索。我在视图的搜索表单中创建了一个下拉菜单,如下所示:

<%= form_tag manage_accounts_administrator_path, :method => 'get', :id => "search-form" do %>
      <%= text_field_tag :search, params[:search], placeholder: 'Search Accounts' %>
      <%= select_tag("search_criteria", options_for_select([['by account number', '1'],['by customer id', '2'],['by customer name (ex: Jane Doe)', '3']])) %>
      <%= submit_tag "Search", :name => nil %>
<% end %>

然后在相应的控制器方法中,我正在这样做:

  def manage_accounts
    # criteria from the "Search by" select menu
    if params[:search]
        case (params[:search_criteria])
        when 1
          @criteria = id
        when 2
          @criteria = customer_id
        when 3 
          @criteria = customer.firstname + ' ' + customer.lastname
        end
        @accounts = Account.where("#{@criteria} LIKE ?", "%#{params[:search]}%").page(params[:page]).per(15)
        @table_heading = "Account Search Results"
    else
        @accounts = Account.order('id').page(params[:page]).per(15)
        @table_heading = "Listing All Accounts"
    end
    respond_to do |format|
      format.js
      format.html {render 'manage_accounts'}
    end
  end

上面事例块中@criteria变量的三个可能值表示"帐户"模型的字段。如您所见,我期望发生的是使用"where"方法执行查询。这个语法是错误的,我得到错误:

ActiveRecord::StatementInvalid in Administrators#manage_accounts Mysql2::Error:您的 SQL 语法有错误;请查看手册 与您的MySQL服务器版本相对应,语法正确 在第 1 行的"类似 '%722586388%'("附近使用:从 accounts WHERE ( 如 '%722586388%"(

显然我做错了。如何插入 @criteria 变量,类似于插入搜索参数的方式?错误告诉我的是变量被完全转义。我已经尝试(猜测(了数十种不同的标点符号组合,但无济于事。我觉得如果我的语法正确,这将起作用。

另外,我读到这是不好的做法,因为它使应用程序容易受到SQL注入的影响。那么,我应该如何以安全的方式写这个声明呢?

谢谢

它是带有 MySQL2 gem 的 rails 4.1.8,我是菜鸟。

你忘了用引号括住你的变量。当执行命中时

@accounts = Account.where("#{@criteria} LIKE ?", "%#{params[:search]}%").page(params[:page]).per(15)

@criteria仍然会nil.因此,例如,由 activerecord 生成的 sql 将被SELECT COUNT(*) FROM accounts WHERE ( LIKE '%722586388%')而不是SELECT COUNT(*) FROM accounts WHERE (id LIKE '%722586388%')

因此,在您的案例中,您必须执行以下操作:

if params[:search]
    case (params[:search_criteria])
    when 1
      @criteria = 'id'
    when 2
      @criteria = 'customer_id'
    when 3 
      @criteria = 'customer.firstname'
    end
if params[:search]
    case (params[:search_criteria])
    when 1
      @criteria = "id"
    when 2
      #assuming you have a customer_id column in your accounts table
      @criteria = "customer_id"
    when 3 
      #assuming you have a customer_name column in your accounts table
      @criteria = "customer_name"
    end

相关内容

  • 没有找到相关文章

最新更新