blogのCRUD機能

前回はrails newで土台作りと設定をしました。

maa0917.hatenablog.com

今回は続きからblogのCRUD機能を実装します。

titleとcontentのみの簡単な機能で作っていきます。 余計なファイルを生成しないようにscaffoldを使わずに実装していきます。

ルートの設定

Rails.application.routes.draw do
  resources :blogs
end

モデルの作成

$ rails g model blogs title:string content:text

(app/models/blog.rb)と(db/migrate/**************_create_blogs.rb)が作成されます。

(db/migrate/**************_create_blogs.rb)

class CreateBlogs < ActiveRecord::Migration[5.2]
  def change
    create_table :blogs do |t|
      t.string :title
      t.text :content

      t.timestamps
    end
  end
end

作成されていることを確認してdb:migrateを実行します。

$ rails db:migrate

コントローラーの作成

$ rails g controller Blogs

アクションの設定をします。

(app/controllers/blogs_controller.rb)

class BlogsController < ApplicationController

  before_action :set_blog, only: [:show, :edit, :update, :destroy]

  def index
    @blogs = Blog.all
  end

  def show
  end

  def new
    @blog = Blog.new
  end

  def edit
  end

  def create
    @blog = Blog.new(blog_params)
    if @blog.save
      redirect_to blogs_path, notice: 'Blog was successfully created.'
    else
      render :new
    end
  end

  def update
    if @blog.update(blog_params)
      redirect_to blogs_path, notice: 'Blog was successfully created.'
    else
      render :edit
    end
  end


  def destroy
    @blog.destroy
    redirect_to blogs_url, notice: 'Blog was successfully destroyed.'
  end

  private

  def set_blog
    @blog = Blog.find(params[:id])
  end

  def blog_params
    params.require(:blog).permit(:title, :content)
  end

end

viewの作成

(app/views/blogs/_form.html.erb)

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

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

  <div class="field">
    <%= form.label :content %>
    <%= form.text_area :content %>
  </div>

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

<% end %>

(app/views/blogs/edit.html.erb)

<h1>Editing Blog</h1>
<%= render 'form', blog: @blog %>
<%= link_to 'Show', @blog %> |
<%= link_to 'Back', blogs_path %>

(app/views/blogs/index.html.erb)

<p id="notice"><%= notice %></p>
<h1>Blogs</h1>
<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Content</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  <tbody>
    <% @blogs.each do |blog| %>
    <tr>
      <td><%= blog.title %></td>
      <td><%= blog.content %></td>
      <td><%= link_to 'Show', blog %></td>
      <td><%= link_to 'Edit', edit_blog_path(blog) %></td>
      <td><%= link_to 'Destroy', blog, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
    <% end %>
  </tbody>
</table>
<%= link_to 'New Blog', new_blog_path %>

(app/views/blogs/new.html.erb)

<h1>New Blog</h1>
<%= render 'form', blog: @blog %>
<%= link_to 'Back', blogs_path %>

(views/blogs/show.html.erb)

<p id="notice"><%= notice %></p>
<p>
  <strong>Title:</strong>
  <%= @blog.title %>
</p>
<p>
  <strong>Content:</strong>
  <%= @blog.content %>
</p>
<%= link_to 'Edit', edit_blog_path(@blog) %> |
<%= link_to 'Back', blogs_path %>

バリデーションの設定

(app/models/blog.rb)

class Blog < ApplicationRecord
  validates :title, presence: true
  validates :content, presence: true
end

以上です。