Railsで関連テーブルのカラムを対象に検索したい


Railsで検索機能を作りたいと思っているのですが、ハマってしまっているのでご教授賜りたく思います。  
Railsで
ArticleとItemというモデルがあり、Itemの中にはURLカラムがあり、そのURLをもとに検索を部分一致検索をかけられる検索フォームを作りたいと思っています。  
現状は`@items = Item.where("url like
%#{params[:search]}").uniq`でフォームに入力されたパラメーター(:search)をもとにlikeで含む検索を可能にしています。  
ここまではできているのですが、ここからItemに紐付いたArticleのレコードを引っ張りたいのですが、方法が思い浮かびません。ArticleとItemはItemにarticle_idがAricleのidと紐付いています。




joinsを使えば関連するテーブルに対する検索を実行できます。

が、文字列に直接パラメータを埋め込むとSQLインジェクションを引き起こすので大変危険です。  
次のように?を使ってバインドするようにしてください。

[code]

    articles = Article.joins(:items).where("items.url LIKE ?", "%#{params[:search]}").uniq
    
[/code]

SQLインジェクションはこちらに詳しい説明があります。

[Rails セキュリティガイド | Rails
ガイド](http://railsguides.jp/security.html#sql%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)

**P.S.**

余談ですが、SQLインジェクションが何かを理解していると以下の4コママンガの面白さが理解できるようになります。

[xkcd: Exploits of a Mom](https://xkcd.com/327/)

[![画像の説明をここに入力](https://i.stack.imgur.com/NOXkO.png)](https://i.stack.imgur.com/NOXkO.png)

**翻訳**

  1. 「もしもし。息子さんの小学校の者です。ちょっと今コンピュータトラブルが発生しています。」
  2. 「あら、たいへん。息子が何か壊したんでしょうか？」「ある意味そうですね。。」
  3. 「お母さん、あなたは本当に息子さんに "Robert'); DROP TABLE Students; --" という名前を付けたんでしょうか？」「ええ。私たちは "ボビーテーブルちゃん" って呼んでます。」
  4. 「とりあえず、我々は今年度の生徒データを喪失しました。あなたにとっては、してやったりでしょうね。」「それといい勉強になったかしら。データベースの入力値はサニタイズすべきだって。」

### 追記

Rails 4.2だと`sanitize_sql_like`というメソッドが使えます。  
使い方はこんな感じです。

[code]

    class Article < ActiveRecord::Base
      has_many :items
      scope :keyword_search, ->(keyword) {
        joins(:items).where("items.url LIKE ?", "%" + sanitize_sql_like(keyword))
      }
    end
    
    # controller
    articles = Article.keyword_search(params[:search])
    
[/code]

LIKE検索では'%'や'_'が特殊な意味を持ちます。  
sanitize_sql_likeを使うと、こうした文字列をエスケープしてくれます。

例: '100%'というキーワードが入力された場合のSQL

[code]

    SELECT ... WHERE (items.url LIKE '%100\%')
    
[/code]

