sk

開発で得たこと

チケットの管理

この記事で行うこと

先着〇〇名まで予約できるチケットを作成できるようにする。

プロジェクトの作成

rails new ticket-reservation

チケットモデルの作成

rails g model Ticket

モデルを作成したら、カラムを書いていきましょう。

db/migrate/20180724113523_create_tickets.rb

class CreateTickets < ActiveRecord::Migration[5.1]
  def change
    create_table :tickets do |t|
      t.string :title        # チケット名
      t.text :body           # チケットの内容
      t.integer :number      # チケット販売可能個数
      t.datetime :expired_at # チケットの予約締切日時
      t.timestamps
    end
  end
end

今回はチケットの販売個数を制限するのと、予約を締切るのでnumber・expired_atカラムを追加します。

Point

expired_atのatは日時(Datetime型)なのでatを使います。時間を含まない日(Date型)の場合は、expired_onのようにonを使用しましょう。
前置詞の前の動詞が過去形になっているのもお約束なので気をつけましょう。

最後に、作成したモデル・カラムをデータベースに反映しましょう。

$ rails db:migrate
== 20180724113523 CreateTickets: migrating ====================================
-- create_table(:tickets)
   -> 0.0009s
== 20180724113523 CreateTickets: migrated (0.0010s) ===========================

チケット情報の入力画面を作成する

チケット情報を入力するためのページ・フォームを作成します。

チケットコントローラの作成

チケット一覧画面と詳細画面も欲しいので一緒に作成しておきましょう。

rails g controller tickets new index

ルーティングは以下のように修正しておます。

config/routes.rb

Rails.application.routes.draw do
  resources :tickets, only: %i(new index)
end

ここではシンボルではなく%記法を使っています。
こちらも便利なrubyの機能です。チェックしておきましょう。

以下のようなパスが作成されるはずです。

$ rails routes
    Prefix Verb URI Pattern            Controller#Action
   tickets GET  /tickets(.:format)     tickets#index
new_ticket GET  /tickets/new(.:format) tickets#new
入力フォームの作成

入力フォームを作成します。
Viewエンジンは少量のコードで済み、可読性の上がるHamlを使用します。

Hamlの導入は以下の記事を参考に行ってください。
www.sendai-freelance.com


続いてnew.html.hamlにView要素を書いていきます。

= form_with(model: @ticket, local: true, html: { role: 'form' }) do |f|
  - if @ticket.errors.any?
    %h4= "#{pluralize(@ticket.errors.count, 'エラーがあります。')}"
    %ul
      - @ticket.errors.full_messages.each do |msg|
        %li= msg

  = f.label :title
  = f.text_field :title, required: true
  %br

  = f.label :body
  = f.text_field :body, required: true
  %br

  = f.label :number
  = f.number_field :number
  %br

  = f.label :expired_at
  = f.datetime_field :expired_at
  %br

  = f.submit

ローカルサーバで確認すると以下のように表示されます。

f:id:sksksksksk:20180724222449p:plain

チケット作成処理

TicketsController.rbにcreateアクションを追加して入力フォームから送られてきた情報をデータベースへ登録します。
Ticketコントローラにcreateアクションとprivate関数としてストロングパラメータを作成しましょう。

app/controllers/tickets_controller.rb

class TicketsController < ApplicationController
  def new
    @ticket = Ticket.new
  end

  def create
    @ticket = Ticket.new(ticket_params)
    if @ticket.save
      redirect_to :tickets, notice: 'チケットを作成しました。'
    else
      render :new
    end
  end

  def index
  end

  private

  def ticket_params
    params.require(:ticket).permit(
      :title,     # チケット名
      :body,      # チケットの内容
      :number,    # チケット販売可能個数
      :expired_at # チケットの予約締切日時
    )
  end
end

createアクションを使用するのでルーティングも変更しましょう。

Rails.application.routes.draw do
  resources :tickets, only: %i(new create index)
end
チケット作成後のリダイレクト先を作成

チケットは作成できるようになりましたが、
このままでは作成後のリダイレクト先に、作成したTicketが表示されません。

リダイレクト先のtickets#indexのViewも整えましょう。

app/views/tickets/index.html.haml

%table
  %thead
    %tr
      %th
      %th チケット名
      %th 内容
      %th チケット販売可能枚数
      %th 締切日
  %tbody
    - @tickets.each.with_index(1) do |ticket, index|
      %tr
        %td= index
        %td= ticket.title
        %td= ticket.body
        %td= ticket.number
        %td= ticket.expired_at

@ticketsをindexアクションで用意しておきましょう。
app/controllers/tickets_controller.rb

  def index
    @tickets = Ticket.all
  end

f:id:sksksksksk:20180724225236p:plain

デザイン

最後にbootstrapを導入してデザインを整えましょう。
bootstrap導入方法の記事はこちらです。
www.sendai-freelance.com

app/views/tickets/new.html.haml

.col-xs-12
  = form_with(model: @ticket, local: true, html: { class: 'form-horizontal', role: 'form' }) do |f|
    - if @ticket.errors.any?
      .alert.alert-danger.alert-dismissable{ role: 'alert' }
        %button.close{ type: 'button', data: { dismiss: 'alert' } }
          %span{ aria: { hidden: 'true' } } &times;
          %span.sr-only Close
        %h4= "#{pluralize(@ticket.errors.count, 'エラーがあります。')}"
        %ul
          - @ticket.errors.full_messages.each do |msg|
            %li= msg
    .form-group
      = f.label :title, class: 'col-sm-2 control-label'
      .col-sm-10= f.text_field :title, class: 'form-control', required: true
    .form-group
      = f.label :body, class: 'col-sm-2 control-label'
      .col-sm-10= f.text_field :body, class: 'form-control', required: true
    .form-group
      = f.label :number, class: 'col-sm-2 control-label'
      .col-sm-10= f.number_field :number, class: 'form-control'
    .form-group
      = f.label :expired_at, class: 'col-sm-2 control-label'
      .col-sm-10= f.datetime_field :expired_at, class: 'form-control'
    .form-group
      .col-sm-offset-2.col-sm-10
        = f.submit class: 'btn btn-primary'

f:id:sksksksksk:20180725204906p:plain


app/views/tickets/index.html.haml

.col-xs-12
  %table.table
    %thead
      %tr
        %th
        %th チケット名
        %th 内容
        %th.text-center チケット販売可能枚数
        %th.text-center 締切日
    %tbody
      - @tickets.each.with_index(1) do |ticket, index|
        %tr
          %td= index
          %td= ticket.title
          %td= ticket.body
          %td.text-center= ticket.number
          %td.text-center= ticket.expired_at

f:id:sksksksksk:20180725210056p:plain


チケット管理は以上になります。



次は、ここまで作ったアプリを本番環境へあげましょう。
www.sendai-freelance.com

ProgateやRailsチュートリアル、プログラミングスクールを通い終えたが現場のコードはかけない、

一体どうやって書くの?と思っているエンジニアのみなさんのためのチュートリアルを公開しています。

チュートリアル