PaizaCloud無料版で24時間以内に学習せよ

Blog Single

「新しい言語を学習しよう」
こう思った時に頭の隅で浮かぶことはなんでしょう。
そう、「あまり時間をかけたくない」ということですね←
「ちょっとやってみたいだけだから環境構築も面倒だ」
つまりは時短学習が必要であると。限られた時間内で学習する癖づけをしたい・・・

そんな時たまたま見つけたツールがありまして。
PaizaCloudというブラウザ上でWeb開発ができるクラウドIDEサービスです。
無料・有料版とありますが、無料版は1サーバーの利用時間が24時間と制限があり、それを経過すると作ったサーバーが消えてしまいます。
もちろん有料版を使用できるのであればそれでいいのですが、
無料版でいかに楽しめるかを日頃追求しているドケチな人間なもので←
というわけで、PaizaCloudを利用して時短学習してみよう!

ルール

自分を追い込むために、個人的に以下のルールを課しました。

  • 最低限CRUD機能をもつページを作成する
  • サーバーが消えるまでの残り時間で自由な追加機能を最低1つ実装する

24時間しかないということで、某海外テレビドラマを勝手に意識してシビアに挑みます。
爆発とかテロとかは起きません←

今回学習対象に選んだのはRuby on Railsです。

サーバー設定

paizaの開発者がPaizaCloudを使用したRuby on Railsの構築の方法をまとめていらっしゃるので、設定方法は下記通りに行いました。

CSSツールの設定

必須ではありませんが今回はCSSツールとしてmaterializeを入れてみました。
headerにリンクを設定する形でもいいですが、今回はgemでやりました。
設定方法は以下をご参考ください!
mkhairi/materialize-sass: Materializecss rubygem for Rails Asset Pipeline / Sprockets

CRUD機能をもつページ

Railsだとscaffoldコマンドでcontroller, view, model, testをまとめて作成できて確かに便利なのですが、初見の方はなるべく個別で作成した方がファイル構成を理解できるかと思います。

私もほぼほぼ初見なのでscaffoldを使わずに作成することにしました。
これも自分への枷です←
作成するものは商品のCRUD機能です。
基本scaffoldで作成したものと同じ仕上がりになるように書いていくので、
ここでは使ったコマンドと独自で手を加えた部分だけをご紹介します。

まずは商品(item)テーブルと、使用するControllerとviewをとりあえず作ります。

$ rails generate model item name:string price:integer stock:integer deleted:boolean:false
$ rake db:migrate
$ rails generate controller items index edit new

続いてルーティングの設定。
resoucesでも良いのですが、今回はscaffoldを使用せずに行くということでルーティングも独自の形式で設定してみます。

# ~/myapp/config/routes.rb
Rails.application.routes.draw do
    get 'items', to: 'items#index'
    get 'items/new', to: 'items#new'
    post 'items/new', to: 'items#create'
    get 'items/:id', to: 'items#edit'
    put 'items/:id', to: 'items#update'
    delete 'items/:id', to: 'items#delete'
end

scaffoldで作成したCRUD機能と変えて実装した部分は、データの削除を物理削除ではなく論理削除とした点です。
処理としては非常に単純で、Model.destroyの代わりにModel.update(deleted: true)で更新しただけです。
それに伴い、一覧ではdeleted = trueのものを取得して表示しています。

# ~/myapp/app/controllers/items_controller.rb
class ItemsController < ApplicationController
    before_action :set_item, only: [:delete]

    # 他メソッドは省略

    # GET /items
    # 一覧ページ
    def index
        @items = Item.where(deleted: false)
    end

    # DELETE /items/:id
    # 削除処理
    def delete
        respond_to do |format|
            if @item.update(deleted: true)
                format.html { redirect_to '/items', notice: "ID: #{@item.id}を削除しました!" }
            else
                format.html { render "items" }
            end
        end
    end

    private
        # パラメータ:idから対象データ取得
        def set_item
            @item = Item.find(params[:id])
        end
end

追加機能

時空飛んでます←
日を跨いでしまったので、残り約6時間。
先ほど作成した商品リストを使って簡易的なショッピングカート機能を作ります。
viewファイルは割愛してテーブル構成とcontrollerの一部処理だけご紹介します。

テーブルとcontrollerとviewの作成には以下のコマンドを使用しました。
非常に単純なカート機能なのでテーブル構成がはちゃめちゃですが←

$ rails generate model shopping total_price:integer deleted:boolean:false
$ rails generate model shopping_item shopping_id:integer item_id:integer quantity:integer deleted:boolean:false
$ rake db:migrate
$ rails generate controller shoppings index cart history

ページ操作的には以下の3点を実装しました。

  1. 商品一覧から、選択した商品をカートへ追加
  2. カート内商品を購入
  3. 購入履歴からキャンセル

1では、shopping_itemsテーブルに一時的に商品IDと個数を保存する処理です。
この時商品の在庫数が足りなければ、カートに追加せず商品一覧ページにリダイレクトさせます。

# ~/myapp/app/controllers/shoppings_controller.rb
class ShoppingsController < ApplicationController

    # POST /shoppings/cart/add/:id
    # カートに入れる処理
    def addCart
        @item = Item.find(params[:id])
        @shoppingItem = ShoppingItem.find_by(deleted: false, shopping_id: nil, item_id: @item.id)
        if @shoppingItem == nil
            @shoppingItem = ShoppingItem.new(item_id: @item.id, quantity: 0, deleted: false)
        end
        @shoppingItem.quantity = @shoppingItem.quantity + 1

        respond_to do |format|
            if @item.stock - @shoppingItem.quantity < 0
                format.html { redirect_to '/shoppings', notice: "在庫が足りません。" }
            else
                if @shoppingItem.save
                    format.html { redirect_to '/shoppings/cart' }
                else
                    format.html { render "shoppings" }
                end
            end
        end
    end
end

2では、1で保存したshopping_itemsのデータを元に購入情報を登録します。
ここで商品(items)の在庫数を減らす処理もまとめて行います。

# ~/myapp/app/controllers/shoppings_controller.rb
class ShoppingsController < ApplicationController

    # POST /shoppings/new
    # 購入処理
    def new
        @shopping = Shopping.new(total_price: 0, deleted: false)
        @cartItems = ShoppingItem.where(deleted: false).where(shopping_id: nil)

        for cartItem in @cartItems do
            @item = Item.find(cartItem.item_id)
            @item.stock -= cartItem.quantity
            @item.save
            @shopping.total_price += @item.price * cartItem.quantity
        end
        @shopping.save

        respond_to do |format|
            if @cartItems.update(shopping_id: @shopping.id)
                format.html { redirect_to '/shoppings', notice: "購入完了しました!" }
            else
                format.html { render "shoppings" }
            end
        end
    end
end

3の購入キャンセル処理は、shoppingsデータを論理削除し、商品の在庫数をロールバックさせます。

# ~/myapp/app/controllers/shoppings_controller.rb
class ShoppingsController < ApplicationController

    # DELETE /shoppings/cancel
    # キャンセル処理
    def cancel
        @history = Shopping.find(params[:id])
        @shoppingItems = ShoppingItem.where(shopping_id: @history.id)

        for shoppingItem in @shoppingItems do
            @item = Item.find(shoppingItem.item_id)
            @item.stock += shoppingItem.quantity
            @item.save
        end

        respond_to do |format|
            if @history.update(deleted: true)
                format.html { redirect_to '/shoppings/history', notice: "ID: #{@history.id}をキャンセルしました!" }
            else
                format.html { render "shoppings/history" }
            end
        end
    end
end

最後に

無事任務遂行。よくやった。 by ◯ャック・◯ウアー

今回はPaizaCloudそのものも初めて使用したので少し設定部分で時間を取られてしまったり、これだけに集中して時間を費やした訳ではなかったので、
あまり個人的に満足の行く出来ではなかったです。(エラー処理はもっと丁寧に書きましょう←)
24時間で消えてしまうPaizaCloud無料版サーバーですが、ちょっとした学習に使ってみると面白いと思います。
ちなみに、消えてもまた一から新しくサーバーを作成することができます。
ただ書いたコードをそのままでは残しておけない(PaizaCloudからgitにあげることは可能です)ので、残さなくてもいい程度のものに使用するのがいいですね!

参考

Posted by Mao Miyaji
千葉にある夢の国を愛して止まない、元「魚のお姉さん」のエンジニア。PHP, TypeScriptメインで、暇さえあれば色々な言語を一かじり。

Other Posts: