LoginSignup
0
0

More than 3 years have passed since last update.

【Rails】カテゴリー機能

Last updated at Posted at 2021-02-20

はじめに

レシピ投稿サイトを作成し、レシピに紐づくカテゴリー機能を実装します。
gemのancestryは使っていません。
RecipeモデルとUserモデルが紐づいており、1ユーザーが複数投稿できる仕様です。その辺りは割愛させて頂きます。
投稿(Recipe)とカテゴリー(Category)のモデル、コントローラーは実装済みで進めさせて頂き、今回は投稿とカテゴリーの紐付けについての内容に重点を置いてQiita投稿させて頂きます。

完成イメージ

入力フォーム
スクリーンショット 2021-02-20 20.38.00 (1).png
レシピ一覧
スクリーンショット 2021-02-20 20.38.51.png

中間テーブルの作成

recipe_category_relationsテーブルを中間テーブルとします。

$ rails g model Recipe_category_relation recipe_id:integer category_id:integer
db/schema.rb
 create_table "categories", force: :cascade do |t|
    t.string "category_name"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "recipe_category_relations", force: :cascade do |t|
    t.integer "recipe_id"
    t.integer "category_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "recipes", force: :cascade do |t|
    t.string "recipe_title"
    t.text "recipe_body"
    t.string "image_id"
    t.integer "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "recipe_food"
  end

投稿のモデル、中間テーブル、カテゴリーテーブルの関連付け

app/models/recipe.rb
class Recipe < ApplicationRecord
  has_many :recipe_category_relations
  has_many :categories, through: :recipe_category_relations
end
app/models/recipe_category_relation.rb
class Recipe_category_relation < ApplicationRecord
  belongs_to :recipe
  belongs_to :category
end
app/models/category.rb
class Category < ApplicationRecord
  has_many :recipe_category_relations
  has_many :recipes, through: :recipe_category_relations
end

through: :recipe_category_relationsの記述で、中間テーブルrecipe_category_relationを経由してrecipeとcategoryが関連付けることができます。

viewに表示

app/views/recipes/new.html.erb
<h1>レシピ投稿</h1><br>
 <%= form_with model:@recipe, url: recipes_path , local:true do |f| %>
   <%= f.attachment_field :image %>
   <%= f.label :title, '料理名'%>
   <%= f.text_field :recipe_title, class:"form-control", placeholder:"料理名" %>
   <%= f.label :category, 'カテゴリ' %>
   <%= f.collection_check_boxes(:category_ids, Category.all, :id, :category_name) do |category| %>
     <%= category.label do %>
       <%= category.check_box %>
       <%= category.text %>
     <% end %>
   <% end %>
   <%= f.label :body, '材料'%>
   <%= f.text_area :recipe_food, class:"form-control", placeholder:"材料をここに" %>
   <%= f.label :body, '作業工程'%>
   <%= f.text_area :recipe_body, class:"form-control", placeholder:"作業工程をここに" %><br>
   <%= f.submit "レシピ投稿", class: "btn btn-warning" %>
 <% end %>

collection_check_boxesというViewヘルパー関数を使って複数選択できるチェックボックスを実装しています。

app/controllers/recipe_controller.rb
class RecipesController < ApplicationController
def new
    @recipe = Recipe.new
  end

  def create
    @recipe = Recipe.new(recipe_params)
    @recipe.user_id = current_user.id
    @recipe.save!
    redirect_to recipe_path(@recipe)
  end

  private
  def recipe_params
    params.require(:recipe).permit(:recipe_title, :recipe_body, :image, :recipe_food, category_ids: [])
  end
end

category_ids はチェックボックスの各チェックに関連付けられるIDが入ります。

app/views/recipes/index.html.erb
<% @recipes.each do |recipe| %>
・
・
・
  <% recipe.categories.each do |category| %>
    <%= category.category_name %>
  <% end %>
<% end %>

上記の記述で、冒頭で表示した2枚目の画像のようにcategory_nameが表示されます。

最後に

今回多対多のアソシエーション、collection_check_boxesメソッドについての実装をしました!
collection_check_boxesメソッドに関してはまだ理解が浅いので、もう少し深く勉強します:sweat:
長くなりましたが、ここまで見て頂きありがとうございました!!:bow:

参考

https://qiita.com/sho012b/items/3a595fde14516081dff5
https://qiita.com/cawaz3/items/e755a58177212f2aca6c

0
0
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
0
0