title: How do I protect this Rails find_by_SQL statement from SQL injection?
body: <p>Thanks for your help with this one! I'm working on a legacy Rails application and I've checked a few sources but haven't been able to make them work for my situation. In Rails 2.3, I've got a search form (index.html.erb) and a controller (search.rb). The controller uses the search fields to build a string, which is saved in the variable @search_string. </p>
  
  <pre><code>    @search_string = ""
  </code></pre>
  
  <p>To show the results of the search, the controller uses:</p>
  
  <pre><code>    @location_matches = Location.paginate_by_sql("select * from locations where #{@search_string} order by nickname asc",  :page =&gt; params[:page], :per_page =&gt; 20)
  </code></pre>
  
  <p>What is the simplest way for me to sanitize the above? I tried</p>
  
  <pre><code>    @location_matches = Location.paginate_by_sql('SELECT * FROM locations WHERE #{@search_string} = ?', @search_string)
  </code></pre>
  
  <p>This throws the error ArgumentError (parameter hash expected). FYI, the @search_string is built with form fields like this:</p>
  
  <p>FORM</p>
  
  <pre><code>    &lt;label for="city"&gt;City&lt;/label&gt;
      &lt;input id="city" name="city" size="30" type="text" value="" /&gt;
  </code></pre>
  
  <p>CONTROLLER</p>
  
  <pre><code>    if params[:city] != ""
      @search_string &lt;&lt; "and city like '%#{params[:city]}%' "
      if @first_term == 'y'
      @search_string = @search_string.gsub('and ', " ")
      @first_term = 'n'
      end
      end
  </code></pre>
  
  <p>I'm pretty sure the individual fields aren't properly parameterized, but rather than go through every field and try and fix it, I was looking for a faster solution by just tweaking the paginate_by_sql statement (I'm new to Rails and am just trying to make a quick fix since the whole app will eventually need upgrading.)</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>I followed the steps in <a href="https://stackoverflow.com/questions/7145645/rails-how-to-sanitize-sql-in-find-by-sql">Rails, how to sanitize SQL in find_by_sql</a> and added an initializer. I also changed my statement to the below. However, when I run my search, I get no results. I also had to delete the ascending condition because it threw an error. Any ideas are very welcome!</p>
  
  <p>Initializer</p>
  
  <pre><code>    class ActiveRecord::Base  
      def self.escape_sql(clause, *rest)
      self.send(:sanitize_sql_array, rest.empty? ? clause : ([clause] + rest))
      end
      end
  </code></pre>
  
  <p>Controller</p>
  
  <pre><code>    query = Location.escape_sql(["SELECT * from locations WHERE #{@search_string} = ?", params[:@search_string]]) 
      @location_matches = Location.paginate_by_sql(query, :page =&gt; params[:page], :per_page =&gt; 20)
  </code></pre>
  
  <p>Log (Looks the same as the code that returns results)</p>
  
  <pre><code>    Parameters: {"city"=&gt;"New York", "commit"=&gt;"Search", "search"=&gt;{"size_category"=&gt;"", "state"=&gt;""}}
  </code></pre>