15
14

More than 3 years have passed since last update.

【gemなし】Railsでラベル機能を作る

Last updated at Posted at 2019-12-20

速攻でラベルのモッグを作りたい時のためにメモ

rails new

$ rails _5.2.4_ new sample-relation -d postgresql --skip-bundle && cd sample-relation && bundle install && rails db:create

scaffoldで無駄なファイルが生成されないよう設定

/config/application.rb
module SampleRelation
  class Application < Rails::Application
    # ここから下を追加
    config.generators do |g|
      g.javascripts false
      g.helper false
      g.test_framework false
    end
  end
end

postテーブル(投稿機能機能)をscaffoldで生成

$ rails g scaffold post title:string details:string

labelテーブル(ラベル機能)をscaffoldで生成

$ rails g scaffold label title:string

post_labelテーブル(postとlabelの中間)をmodelを生成

$ rails g model post_label post:references label:references

アソシエーション

post.rb
class Post < ApplicationRecord
  has_many :post_labels, dependent: :destroy, foreign_key: 'post_id'
  has_many :labels, through: :post_labels, source: :label
end

中間

post_label.rb
class PostLabel < ApplicationRecord
  belongs_to :post, optional: true
  belongs_to :label, optional: true
end

子(ラベル)

label.rb
class Label < ApplicationRecord
  has_many :post_labels, dependent: :destroy, foreign_key: 'label_id'
  has_many :posts, through: :post_labels, source: :post
end

コントローラー

パラメータにlabel_idsを追加

posts_controller.rb
  private
    def post_params
      params.require(:post).permit(:title, :details, label_ids: [] )
    end

ビュー

新規投稿画面

views/posts/new.html.erb

<%= form_with(model: post, local: true) do |form| %>
  <% if post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(post.errors.count, "error") %> prohibited this post from being saved:</h2>

      <ul>
      <% post.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= form.post :title %>
    <%= form.text_field :title %>
  </div>

  <div class="field">
    <%= form.post :details %>
    <%= form.text_field :details %>
  </div>

# 追加

  <div class="field">
  <% Label.all.each do |label| %>
      <% if action_name == 'new' || action_name == 'create' %>
        <%= form.check_box :label_ids, { multiple: true, checked: label[:checked], disabled: label[:disabled], include_hidden: false}, label[:id], "" %>
        <label><%= label.title %></label>
      <% elsif action_name == 'edit' || action_name == 'update' %>
        <%= form.check_box :label_ids, { multiple: true, checked: @task.label_ids.include?(label.id), disabled: label[:disabled], include_hidden: false}, label[:id], "" %>
        <label><%= label.title %></label>
      <% end %>
    <% end %>
  </div>

# ここまで

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

投稿一覧画面

views/posts/index.html.erb
<p id="notice"><%= notice %></p>

<h1>Posts</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @posts.each do |post| %>
      <tr>
      <% post.post_labels.each do |post_label| %>
        <%= post_label.label.title %><br>
      <% end %>
        <td><%= post.title %></td>
        <td><%= link_to 'Show', post %></td>
        <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>
</table>

<br>

<%= link_to 'New post', new_post_path %>

めんどくさがりな方のためにラベルのシードデータの設定

seeds.rb
  5.times do |i|
    Label.create!(title: "sample#{i + 1}")
  end

migrate(テーブルをDBに反映)してseedデータを作ってrails s(サーバー起動)

$ rails db:migrate && rails db:seed && rails s

以上です!

追記

編集時にラベルのチェックを全部外したのにupdateされなかったのでその修正

posts_controller.rb
  def update
    unless params[:task][:label_ids]
      @task.label_on_tasks.delete_all
    end
    respond_to do |format|
      if @task.update(task_params)
        format.html { redirect_to @task, notice: 'Task was successfully updated.' }
        format.json { render :show, status: :ok, location: @task }
      else
        format.html { render :edit }
        format.json { render json: @task.errors, status: :unprocessable_entity }
      end
    end
  end
15
14
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
15
14