LoginSignup
5
4

More than 5 years have passed since last update.

[Rails] そうだ、コントローラで引数を取ろう [ActionArgs]

Posted at

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 は問題ないはず。

さらに副作用として、初めて見た人を

  1. Rails ってこういう書き方もできるのか!
  2. 他のプロジェクトでもやってみよ。
  3. できない :cry:
  4. 何故に?

と困惑させる力を持つ。

……が使ってて気分がいいので使いたい。

使い方

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
5
4
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
5
4