現在、プログラミングスクールにて、主にRubyやRuby on Railsを勉強している者です。この記事を通して少しでもお役に立てられますと幸いです。また、説明不足や誤りがございましたら申し訳ございません。
前提
- MVCの流れや一対多の関連付けについての多少の理解。
- Sorcery gemを使用しているため、current_userメソッドを使っています。
- 機能は最低限となっているため、パーシャル(フォーム用)等は使用しておりません。
- ルーティングは resources :posts を使用しており、標準的なRESTfulルートが生成されています。
Rails.application.routes.draw do
resources :users, only: %i[new create]
resources :posts
end
# 今回使用されるルーティング
posts_path GET /posts(.:format) posts#index
POST /posts(.:format) posts#create
new_post_path GET /posts/new(.:format) posts#new
実行環境
Ruby 3.2.2
Rails 7.0.8
新規投稿の流れ
新規投稿の流れは、(今回は)ヘッダーにある「新規投稿」リンクのクリックから始まります。
<h1 class="text-xl font-semibold">多機能掲示板</h1>
<nav>
<ul class="flex space-x-6">
<%= link_to '新規投稿', new_post_path, class: "hover:text-blue-300 transition-colors duration-300" %>
<%= link_to '投稿一覧', posts_path, class: "hover:text-blue-300 transition-colors duration-300" %>
<%= link_to 'ログアウト', logout_path, class: "hover:text-blue-300 transition-colors duration-300", data: { turbo_method: :delete } %>
</ul>
</nav>
new アクションの実行
new_post_path(新規投稿リンク) をクリックすると、ブラウザは GET メソッドで PostsController の new アクションをリクエストして、結果として関連するnew.html.erbをブラウザにレスポンスとして返します。
このアクションでは、新しい投稿を作成するための空の Post インスタンスが生成され、これが入力フォーム(form_with ヘルパーを使用)に渡されます。
class PostsController < ApplicationController
def new
@post = Post.new
end
end
@post = Post.new は、データベースに保存されていない新しい Post オブジェクト(インスタンス)を作成します。このオブジェクト(インスタンス)は、後ほど出てくるform_withヘルパーを使用した入力フォームにて、ユーザの入力を受け付けるために必要となってきます。
binding.pryを使用して、postインスタンスの中身を確認してみる。
6: def new
7: binding.pry
=> 8: @post = Post.new
9: end
[1] pry(#<PostsController>)> @post = Post.new
=> #<Post:0x0000000******
id: nil,
title: nil,
description: nil,
user_id: nil,
created_at: nil,
updated_at: nil>
[2] pry(#<PostsController>)>
値のセットされていない空のpostインスタンスが生成されていることが確認できます。
新規投稿フォーム
new.html.erb ビューには、form_with ヘルパーを使用したフォームが含まれています。ユーザーがこのフォームに入力し、登録 ボタンをクリックすると、フォームに入力されたデータは PostsController の create アクションに送信されます。
<%= form_with model: @post do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.label :description %>
<%= f.text_area :description %>
<%= f.submit '登録' %>
<% end %>
createアクション
create アクションは、新規投稿フォームから送信されたデータを処理します。form_with により送信されたデータは、このアクションで受け取られ、新しい Post インスタンスに割り当てられます。
class PostsController < ApplicationController
# ...[他のアクション]...
def create
@post = current_user.posts.build(post_params)
if @post.save
redirect_to posts_path, notice: '投稿が正常に作成されました。'
else
render :new
end
end
private
def post_params
params.require(:post).permit(:title, :description)
end
end
ここでは、post_params メソッドを使用してフォームから送信されたデータを安全に扱います。@post.save が成功すると、ユーザーは投稿一覧ページにリダイレクトされ、失敗した場合は新規投稿フォームが再表示されます。
binding.pryをcreateアクションに挟んで、中身を確認してみる。
10: def create
11: binding.pry
=> 12: @post = current_user.posts.build(post_params)
13:
14: if @post.save
15: redirect_to posts_path
16: else
17: render :new
18: end
19: end
[1] pry(#<PostsController>)> params
=> #<ActionController::Parameters {"authenticity_token"=>"VTxLfc*****", "post"=>{"title"=>"テスト", "description"=>"テスト2"}, "commit"=>"登録", "controller"=>"posts", "action"=>"create"} permitted: false>
[2] pry(#<PostsController>)> @post = current_user.posts.build(post_params)
=> #<Post:0x000000**********
id: nil,
title: "テスト",
description: "テスト2",
user_id: 1,
created_at: nil,
updated_at: nil>
[5] pry(#<PostsController>)> if @post.save
[...]
=> #<Post:0x0000000**********
id: 8,
title: "テスト",
description: "テスト2",
user_id: 1,
created_at: Sun, 14 Jan 2024 08:26:36.718209000 UTC +00:00,
updated_at: Sun, 14 Jan 2024 08:26:36.718209000 UTC +00:00>
ここで、@post.save の実行後、新しい投稿データがデータベースに正常に保存されたことが確認できます。この結果、生成された @post インスタンスには、一意のID、タイトル、説明文、ユーザーID、そして作成日時と更新日時が割り当てられています。これにより、新規投稿のプロセスが完了しました。
補足:params メソッドについて
params メソッドは、コントローラ内でHTTPリクエストから送信されたパラメータを取得するために使用されます。
このメソッドは、フォームやURLからの入力を含むリクエストパラメータを扱います。今回の例では、フォームでユーザーが入力したデータ(タイトルと説明文)が params に含まれており、これらは post_params メソッドを通じて安全に抽出・利用されます。
※詳しくは同じスクールに通っている方が、paramsについて詳しく記事にしているので、ご参照いただけますと幸いです。
以上が、Railsの form_with を用いた投稿の作成の流れとなります。
説明ができてない部分や言語化ができてない部分が多々あるかと思いますが、少しでも参考になりますと幸いです。
実際にはさまざまなオプションだったり使用方法がありますので、詳しくはRailsガイド等を参照願います。
ご拝読いただき、ありがとうございました。編集の流れは次回書きたいと思います。
資料