タグ別アーカイブ: StrongParameters

Rails3.2系でStrongParametersを有効にする方法


ゴール

Rails4系でデフォルトに組み込まれたStrongParameterをRails3.2系で使えるようにする。
Rails3.2系では3.1系から組み込まれた Model クラスに対して「attr_accessible」を定義することでMassAssignmentできるWhiteListの属性を指定しているが、この機能(attr_accessible)を無効化して、ControllerでparamsのWhiteListを指定するStrongParameterを利用できるようにさせる。


手順

(github README)strong_parametersについて

Ⅰ. モデルでのMassAssignment対策を無効

attr_accessibleの定義がなくても通るようになる

  1. config/application.rb 内 「config.active_record.whitelist_attributes」 を false にする
  2. Modelにあるattr_accessibleを削除
    attr_accessible があると config.active_record.whitelist_attributes の設定にかかわらずモデルでのMassAssignment対策が有効になる)

以上でモデルでのMassAssignment対策が無効化される( attr_accessible が無効)

Ⅱ. StrongParameters インストール

  • Gemfile に strong_parametersの定義を追加して bundle install
gem "strong_parameters"

Ⅲ. StrongParameters を有効にするための設定

これには今のところ2つの方法がある。適宜利用する方法を選択します。

1.各モデルに定義する

  • strong−parameter を有効にしたいModelに「include ActiveModel::ForbiddenAttributesProtection」を定義する
    メリット:各Modelごとに定義するので、Model毎で設定を入れるか入れないかを定義できる。
class AppVersion < ActiveRecord::Base
  include ActiveModel::ForbiddenAttributesProtection
  …省略
end

2.イニシャライザを新規作成して、そこに定義する

  • 独自のイニシャライザ (strong_parameter.rb)を作成して、その中に「ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)」の定義を入れる。
    メリット:一括で設定できるので全てのModelでStrongParametersを有効にしたいときは手間が省ける。
  # StrongParameterエラー時の挙動 :raise OR :log
  ActionController::Parameters.action_on_unpermitted_parameters = :raise
  
  # ActiveRecordの各ModelにStrongParameterをIncludeする
  ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection)

以上で、通常のRailsコントトーラでStrongParametersを有効にする方法が完了です。
さらっと、2つ目のイニシャライザ作成のところで「ActionController::Parameters.action_on_unpermitted_parameters = :raise」 の設定を書いていますが、StrongParameters でUnpermittedParameters というExceptionが発生するときの挙動を定義しています。ここでは raise するようにします。


ActiveAdmin の対応

1.まずはコードから、、、

ここではデフォルトで作成される admin_userモデルについて書いています。

ActiveAdmin.register AdminUser do 
…省略

  controller do
    def permitted_params
      return {} if request.get?
      {admin_user: params.require(:admin_user)
        .permit(:email, :password, :password_confirmation)}
      # params.permit!     #<= 無条件にparamsを許可する場合
    end
end

■ コードの説明

  • 実装の概要
    controller do ブロックを作ってActiveAdminで採用されている inherited_resourcespermitted_params を定義して、paramsをpermitしたハッシュを返します。

  • return {} if request.get?」について
    HTTP Method の GETの時はぬけるようにして、新規作成(new) の時は除外する(GETの時はparamsにデータがないので)
    How to get ActiveAdmin to work with Strong Parameters?

  • params.permit!」について
    params を無条件ですべてpermitする場合に用いる、ここでは条件を指定してpermitさせている。

2.その他、Tips

[Tips1] Rails3.2系のActiveAdminでは admin_comment がStrongParametersに対応していないようです。

参考コード(active_admin/orm/active_record/comments.rb)
そのため、admin_commentって個人的には使わないし、以下のように無効にしています。

ActiveAdmin.setup do |config|
…省略
  config.allow_commetns = false
…省略
end

[Tips2] ActiveAdmin と言うか devise StrongParametersの対応方法についての参考情報

ActiveAdminでも採用されている 認証Gem devise では StrongParameters の対応方法にbefore_filterを使っているようです。