FullStackEngineer 2022年2月12日更新

カテゴリを付けれるようにする。

Index

一週間のカリキュラム 1週間で、Ruby 〜 Ruby on Railsまでを学ぶ

シリーズの4日目、カテゴリを付けれるようにします。

4日目


記事と対をなすカテゴリを設定する。

今回の内容は

  • 1 カテゴリDBの追加とSEEDデータの追加
  • 2 記事とカテゴリの連携
  • 3 検索と表示

となります。

1 カテゴリDBの追加とSEEDデータの追加

開始前に今までのデータをリセットしておきましょう。

rake db:reset

1-1 カテゴリDB追加

今回カテゴリを新規追加するUIなどは実装せずにDBの作成と初期データをSEEDで投入するという事を行います。

$ bin/rails generate model Category name:string
      invoke  active_record
      create    db/migrate/20220212101824_create_categories.rb
      create    app/models/category.rb
      invoke    test_unit
      create      test/models/category_test.rb
      create      test/fixtures/categories.yml

マイグレーション忘れずに

$ bin/rails db:migrate

1-2 SEEDで初期データ投入

シンプルなカテゴリーを3つほど追加します。 日記、ニュース、特集とします。 ./db/seeds.rb

[
  ['日記'],
  ['ニュース'],
  ['特集']
].each do |name|
  Category.create!(
    { name: }
  )
end

データを投入するためのコマンドを叩きます。

$ bin/rails db:seed

1-3 記事側に関連カテゴリー用のカラムを追加

今回はシンプルにするために、1記事に対して1カテゴリーのみ選択できるようにします。

$ bin/rails generate migration AddCategoryToArticles category:references

また、今回はカテゴリーを指定しなくても良いように、新しく作成されたmigrationファイルの一部を変更します。


class AddCategoryToArticles < ActiveRecord::Migration[7.0] def change add_reference :articles, :category, null: false, foreign_key: true end end

ある程度開発が進んだ場合、このように都度migrationファイルを追加してDBにカラムを足したり、属性を変更したりしてきます。

この後にmigrationを忘れずに

$ bin/rails db:migrate

2 記事のモデルにカテゴリーを連携させる。

DB自体はリレーションが築けましたが、モデルにその事を伝える必要があります。

2-1 モデルに関連付け

app/models/article.rb

class Article < ApplicationRecord
  belongs_to :category # 追加

  validates :title, presence: true
  validates :body, presence: true, length: { minimum: 10 }

  def category # 追加.categoryで呼び出し
    return Category.find_by(id: self.category_id)
  end

end

必須ではありませんが、この時点で一応、カテゴリーサイドからも関連付けを行っておきます。

class Category < ApplicationRecord
  has_many :articles # こちらを追加 1カテゴリーがたくさんの記事に紐付いてる。

  def articles # 追加.articlesで呼び出し
    return Article.where(category_id: id)
  end
end

2-2 フォームでカテゴリーを選べるようにする。

app/views/articles/_form.html.erb

 <div>
    <%= form.label :category_id %><br>
    <%= form.collection_select :category_id, Category.order(:name), :id, :name %>
  </div>

カテゴリーIDのポストを新しく許可します。 app/controllers/articles_controller.rb

  def article_params
    params.require(:article).permit(:title, :body, :category_id)
  end

2-3 カテゴリー名を表示する

表示したい箇所に下記で呼び出し。

app/views/articles/show.html.erb

<p><%= @article.category.name %></p>

3 検索と表示

  • カテゴリー別の一覧記事
  • タイトルを検索

最後に、この2点を実装します。 見た目などはまだまだ放置ですが、それは4日目の最後に行いたいと思います。

3-1 カテゴリー別の一覧記事表示の実装

一覧部分にカテゴリ一覧を表示

app/controllers/articles_controller.rb

 def index
    if params[:category_id] then
      @articles = Article.where(category_id: params[:category_id])
    else
      @articles = Article.all
    end
  end

app/views/articles/index.html.erb

<h1>カテゴリー 一覧</h1>
<ul>
    <% Category.all.each do |category| %>
        <li>
            <%= link_to category.name,articles_path(@article, category_id: category.id) %>
        </li>
    <% end %>
</ul>

3−2 検索機能の実装

さらに追加

app/controllers/articles_controller.rb

 def index
    if params[:category_id] then
      @articles = Article.where(category_id: params[:category_id])

    #この部分を追加
    elsif params[:search_word] then
      @articles = Article.where("title LIKE ?", "%#{params[:search_word]}%")


    else
      @articles = Article.all
    end
  end

app/views/articles/index.html.erb

<h1>検索</h1>
<%= form_with url: "/", method: :get do |form| %>
  <%= form.label :search_word, "タイトル検索:" %>
  <%= form.text_field :search_word ,value: params[:search_word] %>
  <%= form.submit "検索" %>
<% end %>

最新記事一覧

続きを見る

関連コンテンツ

カテゴリー一覧

TOP フルスタックエンジニアを目指すに方々へ 2022年2月6日 GEMライブラリの検索、利用について