Rails ではコントローラに渡ってくる値は
def show
@user = User.find(params[:id])
end
このように取れる。
しかし、 ActionArgs という gem を導入すると
def show(id)
@user = User.find(id)
end
こんな感じで取れるのだ。
post で渡される値もこの通り。
class UsersController < ApplicationController
def create(user)
@user = User.new(user)
...
end
end
別になくても死にはしないが使いたい理由はある。
ただし、他の gem との併用で問題が出てくる場合もある。
cancancan と一緒に使う
Strong Parameters 周りの問題なので、大体の gem は問題ないはず。
さらに副作用として、初めて見た人を
- Rails ってこういう書き方もできるのか!
- 他のプロジェクトでもやってみよ。
- できない
- 何故に?
と困惑させる力を持つ。
……が使ってて気分がいいので使いたい。
使い方
class UsersController < ApplicationController
# params[:id] を必要とする
def show(id)
@user = User.find id
end
# params[:page] はあってもなくてもいい
def index(page = nil)
@users = User.page(page).per(50)
end
# ↑よりも↓の書き方がおすすめと README には書いてある
# params[:page] はあってもなくてもいい
def index(page: nil)
@users = User.page(page).per(50)
end
# params[:post_id], params[:comment] を必要とする
def create(post_id:, comment:)
post = Post.find post_id
if post.create comment
...
end
end
params 変数は消えたわけではないので、今まで通りのコードもちゃんと動くはず。
Strong Parameters
Strong Parameters は二つのやり方がある。
permit メソッドを呼び出す
class UsersController < ApplicationController
def create(user)
@user = User.new(user.permit(:name, :age))
...
end
end
宣言する
- コントローラと対になっているモデルに対して行うとき。
例: UsersController <-> User
class UsersController < ApplicationController
# User モデルの Strong Parameters
permits :name, :age
# user は ActionArgs によって確認されたものが渡される
def create(user)
@user = User.new(user)
end
end
- コントローラと対になっていない時
model_name
を指定する。
class MembersController < ApplicationController
# User モデルの Strong Parameters
permits :name, :age, model_name: 'User'
end
Filter
before_action
系の処理。
普通に書ける。
class UsersController < ApplicationController
before_action :set_user, only: :show
def show
end
private
# params[:id] が id にセットされる
def set_user(id)
@user = User.find(id)
end
end
Scaffold Generator
ActionArgs 流に生成してくれるようになる。
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
permits :name, :age, :email
# GET /users
def index
@users = User.all
end
# GET /users/1
def show
end
# GET /users/new
def new
@user = User.new
end
# GET /users/1/edit
def edit
end
# POST /users
def create(user)
@user = User.new(user)
if @user.save
redirect_to @user, notice: 'User was successfully created.'
else
render action: 'new'
end
end
# PUT /users/1
def update(user)
if @user.update_attributes(user)
redirect_to @user, notice: 'User was successfully updated.'
else
render action: 'edit'
end
end
# DELETE /users/1
def destroy
@user.destroy
redirect_to users_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_user(id)
@user = User.find(id)
end
end