6799

[code]

    search_date = Time.parse(params[:article][:created_at])
    params[:article][:created_at] = search_date..search_date.end_of_day
    @articles = Article.where(article_params)
    
    def article_params
      params.fetch(:article, {}).permit(:category_id, :created_at)
    end
    
[/code]

上記の様なコードを書いていますが、以下の様なエラーが出てしまいます。

[code]

    <ActionController::UnpermittedParameters: found unpermitted parameter: created_at>
    
[/code]

恐らく Range の扱いが特殊なためだと思われるのですが、 Strong Parameters で Range
を使用するには、どうすればよろしいでしょうか。


CC BY-SA 3.0
2015-02-19T21:20:10.040
6795
2015-02-20T10:24:50.423
2015-02-19T23:15:34.713
4978
8414
question
ruby-on-rails
Range を permit すると ActionController::UnpermittedParameters エラーが上がる


そもそも検索条件として`article_params`を使っているのが変ですね。  
`article_params`を使うのであればcreateやupdateなど、データを更新する場合だと思います。

このケースであれば、以下のようなコードでよいと思うのですがいかがでしょうか？

[code]

    search_date = Time.parse(params[:article][:created_at])
    date_range = search_date..search_date.end_of_day
    @articles = Article.where(created_at: date_range)
    
[/code]

### 余談：Time.parseメソッドについて

`Time.parse`と`Time.zone.parse`ではタイムゾーンの扱いが微妙に異なります。  
個人的にオススメなのは後者です。

詳しい理由はこちらの記事を参考にしてみてください。

[RubyとRailsにおけるTime, Date, DateTime,
TimeWithZoneの違い](http://qiita.com/jnchito/items/cae89ee43c30f5d6fa2c)

### 余談、もとい脱線？: 検索フォームを便利に作成するgem

なんとなくの予想ですが、この件は検索条件を指定するフォームがあって、そこの入力値から検索を実行しているコードのような気がします。

そして、`= form_for @article, url: article_search_path, method: :get do |f|`
のようなコードを書いているんじゃないでしょうか？

もしそうだとしたら、Ransackというgemを使うと結構楽に検索フォームが作れます。

<https://github.com/activerecord-hackery/ransack>

Ransackの使い方はネットにいろいろ情報が載っています。  
たとえばこのページとかが参考になるかもしれません。

  * [検索用のgem「ransack」を使ってみる](http://qiita.com/LuckOfWise/items/e020e896e71d47d0c6a4)

Ransackを活用するとそもそもこういった問題が発生しなくなると思います。

全然的外れなアドバイスだったらすいません。  
とりあえずご参考までに。


CC BY-SA 3.0
2015-02-20T01:06:16.247
6799
2015-02-20T10:24:50.423
2015-02-20T10:24:50.423
85
85
6795
answer


`actionpack-4.2.0/lib/action_controller/metal/strong_parameters.rb`だと515行目あたりに`PERMITTED_SCALAR_TYPES`という許可するクラスの一覧があって`Range`がそこには含まれていないので`Range`を渡すとフィルタで消されてしまってますね。

ところで、Strong paramatersは元々Mass assignment脆弱性対策のために導入されたものです。これを

  * コントローラが受け入れるべきパラメータの検証
  * コントローラがモデルに渡す際のパラメータの検証

のどちらと解釈するかですが、ニュアンスとしては前者ではないかなと思います。とすると、値を書き換えるのであればまず先に検証してから編集した方が良いのではないですかね。

[code]

    search_params = article_params
    search_date = Time.parse(params[:article][:created_at])
    search_params[:created_at] = search_date..search_date.end_of_day
    @articles = Article.where(search_params)
    
[/code]


CC BY-SA 3.0
2015-02-20T01:58:48.050
6803
2015-02-20T01:58:48.050
5793
6795
answer