<<前 [TOP] 次>>
今までSQLite環境でやってきたアプリケーションの実装をMySQL環境でやっていきます。
Railsのバージョンも4.2に変更しているので、記述が若干異なっています。
「shop」フォルダにある「Gemfile」というファイルを開いて、最後に「gem 'coffee-script-source', '1.8.0'
」という記述を追加しましょう。
その後、コマンドプロンプトで「shop」フォルダに移動して「bundle update coffee-script-source
」と入力します。
コマンドプロンプトで「rails server
」と入力すると「WEBrick」が起動します。
Rails5.1ではWebサーバが「Puma」でしたが、Rails4.2では「WEBrick」を使用することになります。
使用方法は変わりません。
てブラウザで「http://localhost:3000/goods」を確認してみましょう。
このようなindexページが表示されれば大丈夫です。
「app/models/good.rb」ファイルを以下のようにしてvalidates(バリデート)を実装します。
文字コードは「UTF-8」にします。
【app/models/good.rb】
class Good < ActiveRecord::Base validate :price_validate #Railsで標準で用意されている検証メソッド #指定されたフィールドが存在し、その内容が空でないことを確認。 validates_presence_of :title, :image_url, :maker, :category, :message => "が空の状態で保存することは出来ません。" #priceフィールドに数字か入力されているか検証。 validates_numericality_of :price, :message => "が有効な数値ではありません。" #titleフィールドに保存しようとする名称が存在していないかどうかを確認。 validates_uniqueness_of :title, :message => "はすでに存在しています。" #フィールドの値が正規表現に一致するかどうかをチェック。 #.gif,.jpg,.pngのどれかで終わっていることを確認。 validates_format_of :image_url, :with => /\a|\.jpg$|\.png$|\.gif$\z/, :message => "はGIF,JPG,PNG画像でなければなりません。" #商品の価格が正の数であることを確認する。 #価格フィールドが空でないときだけチェックをする。 protected def price_validate errors.add(:price, "は0より大きくなければなりません。") unless price.nil? || price > 0.0 end end
トップページの見た目を変えます。
【app/views/goods/index.html.erb】
<p id="notice"><%= notice %></p> <h1>Railsはじめてマート</h1> <table> <thead> <tr> <th>商品画像</th> <th>商品ID</th> <th>商品名</th> <th>説明</th> <th>画像URL</th> <th>価格</th> <th>登録日</th> <th>メーカー</th> <th>カテゴリー</th> <th colspan="3"></th> </tr> </thead> <tbody> <% @goods.each do |good| %> <tr> <td text-align:center;><img height="80" src="<%=h good.image_url %>"/></td> <td><%= good.goods_id %></td> <td><%= good.title %></td> <td><%= good.description %></td> <td><%= good.image_url %></td> <td><%= (good.price).to_i %>円</td> <td><%=h ((good.date).to_date).strftime('%Y年%m月%d日') %></td> <td><%= good.maker %></td> <td><%= good.category %></td> <td><%= link_to '詳細', good, class: 'btn' %></td> <td><%= link_to '編集', edit_good_path(good), class: 'btn' %></td> <td><%= link_to '削除', good, method: :delete, data: { confirm: '本当に削除してもよろしいですか?' }, class: 'btn' %></td> </tr> <% end %> </tbody> </table> <br> <%= link_to '商品登録', new_good_path, class: 'btn' %>
価格を表示する部分を整数表示させたかったので「.to_i 」メソッドを使用した記述に変更しています。
<td><%= (good.price).to_i %>円</td>
スタイルシートを実装します。
【app/assets/stylesheets/scaffold.scss】
h1:first-letter { font-size: 2em; color: #7172ac; } h1 { position: relative; color: #333333; text-shadow: 0 0 2px white; } h1:before { content: ""; position: absolute; background: #9de5ff; width: 50px; height: 50px; border-radius: 50%; top: 50%; /* border: dashed 1px white; */ left: -15px; -moz-transform: translateY(-50%); -webkit-transform: translateY(-50%); -ms-transform: translateY(-50%); transform: translateY(-50%); z-index: -1; } table { width: auto; border-spacing: 0; font-size:14px; } table th { color: #fff; padding: 8px 15px; background: #7172ac; background:-moz-linear-gradient(rgba(34,85,136,0.7), rgba(34,85,136,0.9) 50%); background:-webkit-gradient(linear, 100% 0%, 100% 50%, from(rgba(34,85,136,0.7)), to(rgba(34,85,136,0.9))); font-weight: bold; border-left:1px solid #258; border-top:1px solid #258; border-bottom:1px solid #258; line-height: 120%; text-align: center; text-shadow:0 -1px 0 rgba(34,85,136,0.9); box-shadow: 0px 1px 1px rgba(255,255,255,0.3) inset; } table th:first-child { border-radius: 5px 0 0 0; } table th:last-child { border-radius:0 5px 0 0; border-right:1px solid #258; box-shadow: 2px 2px 1px rgba(0,0,0,0.1),0px 1px 1px rgba(255,255,255,0.3) inset; } table tr td { padding: 8px 15px; border-bottom: 1px solid #84b2e0; border-left: 1px solid #84b2e0; text-align: center; } table tr td:last-child { border-right: 1px solid #84b2e0; box-shadow: 2px 2px 1px rgba(0,0,0,0.1); } table tr { background: #fff; } table tr:nth-child(2n+1) { background: #f1f6fc; } table tr:last-child td { box-shadow: 2px 2px 1px rgba(0,0,0,0.1); } table tr:last-child td:first-child { border-radius: 0 0 0 5px; } table tr:last-child td:last-child { border-radius: 0 0 5px 0; } table tr:hover { background: #fffafa; cursor:pointer; } .btn { position: relative; display: inline-block; font-weight: bold; padding: 12px 0 8px; text-decoration: none; color: #67c5ff; transition: .4s; } .btn:before{ position: absolute; content: ''; width: 100%; height: 4px; top:100%; left: 0; border-radius: 3px; background:#67c5ff; transition: .2s; } .btn:after{ position: absolute; content: ''; width: 100%; height: 4px; top:0; left: 0; border-radius: 3px; background:#67c5ff; transition: .2s; } .btn:hover:before { top: -webkit-calc(100% - 3px); top: calc(100% - 3px); } .btn:hover:after { top: 3px; } body { background-color: #fff; color: #333; margin: 33px; font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 18px; } p, ol, ul, td { font-family: verdana, arial, helvetica, sans-serif; font-size: 13px; line-height: 18px; } pre { background-color: #eee; padding: 10px; font-size: 11px; } div { &.field, &.actions { margin-bottom: 10px; } } #notice { color: green; } .field_with_errors { padding: 2px; background-color: red; display: table; } #error_explanation { width: 450px; border: 2px solid red; padding: 7px 7px 0; margin-bottom: 20px; background-color: #f0f0f0; h2 { text-align: left; font-weight: bold; padding: 5px 5px 5px 15px; font-size: 12px; margin: -7px -7px 0; background-color: #c00; color: #fff; } ul li { font-size: 12px; list-style: square; } } label { display: block; }
次は登録フォームの実装です。
【app/views/goods/new.html.erb】
<h1>商品の登録</h1> <%= render 'form', good: @good %> <%= link_to 'トップページに戻る', goods_path, class: 'btn' %>
【app/views/goods/_form.html.erb】
<%= form_for(@good) do |f| %> <% if @good.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@good.errors.count, "error") %> 商品を登録することが出来ません。</h2> <ul> <% @good.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <br> <div class="field"> <%= f.label :goods_id, :商品ID %> <%= f.number_field :goods_id, id: :good_goods_id %> </div> <div class="field"> <%= f.label :title, :商品名 %> <%= f.text_area :title, id: :good_title %> </div> <div class="field"> <%= f.label :description, :詳細 %> <%= f.text_area :description, id: :good_description %> </div> <div class="field"> <%= f.label :image_url, :画像URL %> <%= f.text_area :image_url, id: :good_image_url %> </div> <div class="field"> <%= f.label :price, :価格 %> <%= f.number_field :price, id: :good_price %><span> 円</span> </div> <div class="field"> <%= f.label :date, :登録日 %> <%= f.datetime_select :date, id: :good_date, :use_month_numbers => true, :default => Time.now %> </div> <div class="field"> <%= f.label :maker, :メーカー %> <%= f.text_area :maker, id: :good_maker %> </div> <div class="field"> <%= f.label :category, :カテゴリー %> <%= f.select(:category, [['選択して下さい', ''],['本', '本'],['家電', '家電'],['おもちゃ', 'おもちゃ'], ['生活用品', '生活用品']]) %> </div> <div class="actions"> <%= f.submit('登録', :class=> 'fbtn') %> </div> <% end %>
変更点は「date」フィールドの部分に「datetime_select」メソッドを使用したところです。
<%= f.datetime_select :date, id: :good_date, :use_month_numbers => true, :default => Time.now %>
オプションで「:use_month_numbers => true」と指定することで、月の英語表示を数字に変えることが出来ます。
さらに「:default => Time.now」とすることで、デフォルトを現在の日時に指定しています。
コントローラの実装です。
【app/controllers/goods_controller.rb】
class GoodsController < ApplicationController before_action :set_good, only: [:show, :edit, :update, :destroy] # GET /goods # GET /goods.json def index @goods = Good.all end # GET /goods/1 # GET /goods/1.json def show end # GET /goods/new def new @good = Good.new end # GET /goods/1/edit def edit end # POST /goods # POST /goods.json def create @good = Good.new(good_params) respond_to do |format| if @good.save format.html { redirect_to @good, notice: '商品が登録されました。' } format.json { render :show, status: :created, location: @good } else format.html { render :new } format.json { render json: @good.errors, status: :unprocessable_entity } end end end # PATCH/PUT /goods/1 # PATCH/PUT /goods/1.json def update respond_to do |format| if @good.update(good_params) format.html { redirect_to @good, notice: '商品の登録内容が更新されました。' } format.json { render :show, status: :ok, location: @good } else format.html { render :edit } format.json { render json: @good.errors, status: :unprocessable_entity } end end end # DELETE /goods/1 # DELETE /goods/1.json def destroy @good.destroy respond_to do |format| format.html { redirect_to goods_url, notice: '商品を削除しました。' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_good @good = Good.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def good_params params.require(:good).permit(:goods_id, :title, :description, :image_url, :price, :date, :maker, :category) end end
表示(show)の実装です。
【app/views/goods/show.html.erb】
<h1>商品内容の表示</h1> <br> <p id="notice"><%= notice %></p> <span> </span><img height="100" style="border:ridge 5px #c0c0c0" src="<%= @good.image_url %>"/> <br> <br> <p> <font size="4px"> <strong>【商品ID:】 </strong> <%= @good.goods_id %> </font> </p> <p> <font size="4px"> <strong>【商品名:】 </strong> <%= @good.title %> </font> </p> <p> <font size="4px"> <strong>【説明:】 </strong> <%= @good.description %> </font> </p> <p> <font size="4px"> <strong>【画像URL:】 </strong> <%= @good.image_url %> </font> </p> <p> <font size="4px"> <strong>【価格:】 </strong> <%= (@good.price).to_i %><span>円</span> </font> </p> <p> <font size="4px"> <strong>【登録日:】 </strong> <%=h ((@good.date).to_date).strftime('%Y年%m月%d日') %> </font> </p> <p> <font size="4px"> <strong>【メーカー:】 </strong> <%= @good.maker %> </font> </p> <p> <font size="4px"> <strong>【カテゴリー:】 </strong> <%= @good.category %> </font> </p> <br> <span> </span><%= link_to '編集', edit_good_path(@good), class: 'btn' %> <span> </span> <%= link_to '戻る', goods_path, class: 'btn' %>
編集(edit)の実装です。
【app/views/goods/edit.html.erb】
<h1>商品の編集</h1> <%= render 'form', good: @good %> <br> <%= link_to '表示', @good , class: 'btn'%><span> </span> <%= link_to '戻る', goods_path , class: 'btn' %>
レイアウトの実装です。
【app/views/layouts/application.html.erb】
<!DOCTYPE html> <html> <head> <title>Railsはじめてマート</title> <%= csrf_meta_tags %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %> </head> <body> <%= yield %> </body> </html>
↓↓クリックして頂けると励みになります。