3

私のコントローラーアクションでは、次のようになります。

def index
    @articles = (params[:mine] == "true") ? current_user.articles : Article.search(params[:search])
    @articles = @articles.sort! { |a,b| b.created_at <=> a.created_at }
    @articles = Kaminari.paginate_array(@articles).page(params[:page]).per(25)

    respond_to do |format|
      format.html
      format.json { render json: @articles }
    end
end

そしてモデルでは:

  def self.search(search)
    if search.present?
      where("category LIKE ? OR article_type LIKE ?", "%#{search}%","%#{search}%")
    else
      find(:all)
    end
  end

クエリでパラメータを直接使用すると、SQLインジェクションが可能になることを理解しています。ここでは、パラメータを直接whereクエリに渡しますArticle.search(params[:search])。これはSQLインジェクションの傾向がありますか?もしそうなら、どうすればそれをより安全にすることができますか?また、コントローラーコードを正しく記述したかどうかにも疑問があります。コントローラコードのリファクタリングに関する提案があれば、私に知らせてください。彼らは非常に高く評価されます。どうもありがとう!

4

1 に答える 1

3

クエリでは、によって提供されるメソッドを使用するActiveRecordか、Arelそれ自体を実行する必要があります(ただし、現在のメソッドは問題ありません)。これにより、SQLが適切にエスケープされます。Arel今すぐ詳細に立ち入りたくない場合は、 squeelmeta_where(古いレールの場合)などのgemを使用できます。

クエリ構築のほとんどのニーズにこれらのgemを強くお勧めします。より高度なものは、を使用して直接書き出すことができますArel

gemの助けを借りずに、基本的な構文でmatchesLIKE)を直接実行できるかどうかは、まだ思い出せません。ActiveRecord.whereしかし、あなたは間違いなくこれを直接で行うことができますArel

articles = Article.arel_table
articles = articles[:category].matches("%#{search}%").
  or(articles[:article_type].matches("%#{search}%"))

この時点で、を使用to_aするarticlesか、を使用してこれをモデルto_sqlに渡すことができます。Articlefind_by_sql

Article.find_by_sql articles.to_sql

will_paginateにはpaginate_by_sqlメソッドがあり、メソッドもあるとkaminari思います(または、少なくともそうなると思います)。

コントローラーコードについては、可能であれば、あらゆる種類の並べ替えオプションをデータベースに渡します(これはページネーションにも当てはまります)。

articles.sort('`articles`.created_at DESC')

現在使用している方法では、[許可された]レコードを「すべて」取得して並べ替え、制限を戻しますper_page。この場合、どの種類がページ付けの目的を完全に無効にしますか。

少なくとも、現在の設定を次のようにリファクタリングしてみてください。

@articles = (params[:mine] == "true") ? current_user.articles : Article.search(params[:search])
@articles = @articles.sort('`articles`.created_at DESC').page(params[:page]).per(25)

ActiveRelationRailsがデータベースへのクエリをレイジーロードする方法により、これに追加のものをバインドできます。

于 2012-08-26T04:40:57.647 に答える