9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Rails]カテゴリを選択するフォームを作りたい

Last updated at Posted at 2020-07-09

こんにちは。
現在Railsで掲示板をつくっています。

掲示板のスレッドをカテゴリで分類して表示したかったので、スレッドをたてる時にカテゴリーを選択するようにしようと思って実装しました。

最近Railsを触り始めたので詳しい人いたらマサカリおねがいします。

バージョンとか

Ruby 2.5
Rails 5.1

DB・準備

カテゴリにたくさんのスレッドが紐づいている設計です
スクリーンショット 2020-07-09 12.08.06.png

モデル間の設定も忘れずに...

thread.rb
class Thread < ApplicationRecord
	belongs_to :category
end
category.rb
class Category < ApplicationRecord
	has_many :threads
end

まずはカテゴリを登録する

カテゴリがないと始まらないので、登録しましょう。コンソールからでもいいのですが、今後カテゴリを追加していくと考えて、登録フォームを作ってしまいます。登録したら一覧ページに飛ぶ様にしてあります。

はじめに、routes,controllerを書いていく

  • ルーティング
routes.rb
Rails.application.routes.draw do
  root 'thread#index'
  resources :thread #スレッドのルーティングも書いちゃいます
  resources :categories
end
  • コントローラ
categories.controller.rb
class CategoriesController < ApplicationController
	def new
		@category = Category.new
	end

	def create
		@category = Category.new(category_params)
		if @category.save
			redirect_to categories_path, notice: "登録しました"
		else
			render :new
		end
	end

	def index
		@categories = Category.all
	end

	private
	def category_params
		params.require(:category).permit(:name)
	end
end

  • 登録フォーム
スクリーンショット 2020-07-09 12.26.28.png
new.html.erb
<div class="col-sm-12">
	<h2 class="text-center">カテゴリの追加</h2>
	<%= form_with model: @category, local: true do |f| %>
		<div class="form_input">
			<%= f.label :name %>
			<%= f.text_field :name, class:"form-control" %>
		</div>
		<div class="form_action row">
			<%= f.submit "登録する", class: "btn col-sm-12 submit_btn" %>
		</div>
	<% end %>
</div>
  • 一覧ページ
スクリーンショット 2020-07-09 12.28.24.png

これはとりあえず表示できればいいかなと

index.rb
<div>
	<% @categories.each do |category| %>
		<%= category.name %>
	<% end %>
</div>

スレッド投稿フォームをつくる

登録ができたので、あとはスレッドの投稿フォームでカテゴリを選べる様にします。

  • コントローラ
threads_controller.rb
class ThreadsController < ApplicationController
  def new
    @thread = Thread.new
  end

  def create
    @Thread = Thread.new(board_params)
    if @thread.save
      redirect_to thread_path(@thread), notice: "投稿が完了しました"
    else
      render :new
    end
  end

  def show
    @thread = Thread.find(params[:id])
  end

  private
  def board_params
    params.require(:thread).permit(:title,:body)
  end
end

  • 投稿ページ
スクリーンショット 2020-07-09 12.36.23.png

collection_selectで選択フォームを作ることができます。

使い方としては、こんな感じに使うのですが...
collection_select(オブジェクト名, メソッド名, 要素の配列, value属性の項目, テキストの項目 [, オプション or HTML属性 or イベント属性])

今回の例だと、Category.allが「要素の配列」の部分にあたりますね。
もしかしたら、Category.allって書くよりもコントローラの方で変数に入れちゃってviewで使用。という様な形の方がいいのかもしれません。

ここはだれか指摘していただけると助かります。

threads/new.index.erb
<div class="col-sm-12">
	<h2 class="text-center">スレッド立てる</h2>
	<%= form_with model: @thread, local: true do |f| %>
		<div class="form_input">
			<%= f.label :title %>
			<%= f.text_field :title, class: "form-control" %>
		</div>
		<div class="form_input">
			<%= f.label :body %>
			<%= f.text_area :body, class: "form-control" %>
		</div>
		<div class="form_input">
			<%= f.label :category_id %>
			<%= f.collection_select :category_id, Category.all, :id, :name,
															:include_blank => "カテゴリを選択してください" %>
		</div>
		<div class="form_action row">
			<%= f.submit "投稿する", class: "btn col-sm-12 submit_btn" %>
		</div>
	<% end %>
</div>

以下の様な感じで選択できるようになります。

スクリーンショット 2020-07-09 12.37.45.png

おわりに

最後までみてくれてありがとうございました。
これからたくさん記事書いて、どんどんアウトプットしていこうと思います。

9
11
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
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?