LoginSignup
0
0

More than 5 years have passed since last update.

Rails4 Parameters レイヤーを追加してみる

Posted at

動機

Rails4では、StrongParameterが採用され、コントローラに、permit処理を書く、というのがよくやるパターンです。(scaffoldもそうなっている)べつにこのままでもよいのですが、入力を受け取りmodelとviewへの命令に変換するというMVCにおけるコントローラ責務を考えてみたとき、リクエストパラメータを検証することは、責務として切り出しておいてもおかしくはなさそうです。特に
- コントローラが肥大化してきた
- 何か権限に基づいて、許容するパラメータを変更したくなったりして、permit処理にロジックが入り込む

などでコードの見通しが悪くなったり

  • 名前空間をきって同じリソースを扱うコントローラを複数つくったが、permit処理は同じものを使いたい、けどコードが重複してしまう

といった場合にはなんらかの形で切り出したいと思ってしまいます。

共通化したいならconcernsに書けば?????

というご指摘もあるんですが、今回は、

パラメータ検証するという責務をコントローラから切り出す

ということにチャレンジしてみたいと思います。私が行っているプロジェクトで採用してみて、粉の設計判断がどういう結果をもたらすか、検証してみたいと思います。

いろいろご指摘などいただけると幸いです!

設定

app配下にparametersをつくります。その際、アプリケーションが自動でファイルを読み込めるように以下の設定を追加します。

application.rb
module SampleProject
  class Application < Rails::Application
    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration should go into files in config/initializers
    # -- all .rb files in that directory are automat"ically loaded.

    config.autoload_paths += %W(#{config.root}/app/parameters)

実装 

イベント(Event)という
- タイトル(title)
- 開始時刻(start_datetime)
- 終了時刻(end_datetime)
- 本文(content)
いうデータをもつリソースを扱うコントローラを考えます。
イベントは、コミュニティ(community)ごとに登録/編集することができ、またユーザのダッシュボード画面でも編集することができます。

このような、要件を満たすものを作る場合、以下のようなルーティングで、それぞれコントローラを割り当てます

routes.rb
  resource :user_account do
    namespace :user_accounts do
      resources :events do
      end
    end
  end

  resources :communities do
    resources :events do
    end
  end


event_parameter.rb
class EventParameter
  def self.create(params)
    params.require(:event)
      .permit(:title, :content, :start_datetime, :end_datetime)
  end
end

app/controllers/user_accounts/event_controller.rb
class UserAccounts::EventsController < ApplicationController  
  def update
    respond_to do |format|
      if @event.update(EventParameter.create(params))
      ....
  end
  .....
end
app/controllers/events_controller.rb

class EventsController < ApplicationController

  def create
    @event = Event.new(EventParameter.create(params))
    ....
  end
end

すっきりしましたね!!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0