🙌

Rails paramsって何か.

2022/03/16に公開

paramsとは...

paramsはrailsで送られてきた値を受け取るメソッド.

params[:カラム名]

上記のように受け取ることができる.

検証用アプリケーションの作成

まず準備として簡単なアプリケーションをscaffoldを使用して作成し、rails db:migrateも一緒にしていきます。

$ rails g scaffold Post title:string body:text
$ rails db:migrate

以下のようなアプリケーションが作成されます。

ActiveRecord::Schema.define(version: 2022_03_09_061023) do
  create_table "posts", force: :cascade do |t|
    t.string "title"
    t.text "body"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end
end

$ rails cを使用して、データを直接作成していきます。

Post.create(title: 'テスト1', body: '内容1')
Post.create(title: 'テスト2', body: '内容2')
Post.create(title: 'テスト3', body: '内容3')
Post.create(title: 'テスト4', body: '内容4')

link_toの受け渡し

まずは、index.html.erbの

posts/index.html.erb
<tbody>
  <% @posts.each do |post| %>
    <tr>
      <td><%= post.title %></td>
      <td><%= post.body %></td>
      <td><%= link_to 'Show', post %></td>

      # ここのEditの edit_post_path(post) の部分に注目します
      <td><%= link_to 'Edit', edit_post_path(post) %></td>
      <td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
</tbody>

上記の@postsには、以下のようにコントローラでPostのデータをすべて渡してます。

"posts_controller"
def index
  @posts = Post.all
end

以下のEditのlink_toについて説明します。

つまりここでは各postのidが入っていることになります。

link_to <%= link_to 'Edit', edit_post_path("eachで渡されたpostのidが入る") %>

ここでpostコントローラのeditアクションへのルーティングを確認します。

edit_post GET /posts/:id/edit(.:format) posts#edit

上記のように:idを含む形にURLになっています。

なのでEditをクリックしたときのURLは、以下のようになってます。

http://localhost:3000/posts/1/edit

クリック後にeditページを表示するときにpostsコントローラのeditアクションを経由してedit.html.erbを表示しますが、そのときにparams[:id]でURLから受け取ってることになります。

def edit
  @post = Post.find(params[:id])
end

formでよるパラメータの受け渡し

railsでformを使用する場合、form_withを使用するのが一般的です。
posts/new.html.erbファイルは以下のようになっています。

<%= form_with(model: @post, local: true) do |form| %>
  <div class="field">
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>
  <div class="field">
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>
  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

ここでルーティングを確認しておきます。

posts POST /posts(.:format) posts#create
new_post GET /posts/new(:format) posts#new

form_withで送信をクリックした時、postsコントローラのcreateアクションにPOSTメソッドでデータが送信されます。
では、それがpostsコントローラのcreateアクションではどのように受け取ってるか。ここでは見ていきます。

def create
  @post = Post.new(post_params)

  if @post.save
    redirect_to post_url(@post), notice: "Post was successfully created."
  else
    render :new
  end
end

実際にscaffoldで記述されたcreateアクションを見てみると上記のように記述されています。
@post = Post.new(post_params)post_paramsってなに??ってなります...
さらにここを見ていきます。
ざっくり説明するとストロングパラメータという仕組みを使用しています。

このposts_paramsは、コントローラの下の法に記述されてます。

def post_params
  params.require(:post).permit(:title, :body)
end

この記述がストロングパラメータで受け取る仕組みになってます。
この中の記述を見ていきます。
まず、requireは直訳すると"必要とする" permitは"許可"という意味になります。

このストロングパラメータという仕組みを使ってcreateアクションで受け取ってるということになります。

なぜ直接、値を渡していけないか...

以下のようにデータを取得することもできます。

@post = Post.new(:post)
# これだと以下のようにデータを取り出すことができる。
"rails c"
irb(main):001:0> post = Post.new(title: 'a', body: 'ka')
# Post.new(title: 'a', body: 'ka')とPost.new(:post)は同じ意味です。
   (3.2ms)  SELECT sqlite_version(*)
=> #<Post id: nil, title: "a", body: "ka", created_at: nil, updated_at: nil>
irb(main):002:0> post.title
=> "a"
irb(main):003:0> post.body
=> "ka"

直接データが入れられるし取り出せるし、とても便利に見えます。
上記のような機能のことをマスアサイン機能と言います。
ですが、これを使用すると...
悪意あるユーザーがいる場合、よきせぬ危険があります。

上記の理由からストラングラパメータを使用してデータの受け渡しをします。

Discussion