学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Rails6.0 | 仕事売買サイトの構築 | 22 | 仕事登録

[21]仕事ビュー << [ホームに戻る] >> [23]dropzone


仕事の内容を登録できるようにします。
実際に登録して試すことはまだできません。


「app\views\gigs\edit.html.erb」ファイルを以下のように編集します。


app\views\gigs\edit.html.erb

<section class="section">
  <div class="container">
    <div class="steps" id="stepsDemo">

      <!-- 5つのステップ -->
      <div class="step-item <%= 'is-active' if @step == 1 %> <%= 'is-completed' if @step > 1 %>">
        <div class="step-marker">1</div>
        <div class="step-details">
          <p class="step-title">概要</p>
        </div>
      </div>
      <div class="step-item <%= 'is-active' if @step == 2 %> <%= 'is-completed' if @step > 2 %>">
        <div class="step-marker">2</div>
        <div class="step-details">
          <p class="step-title">価格</p>
        </div>
      </div>
      <div class="step-item <%= 'is-active' if @step == 3 %> <%= 'is-completed' if @step > 3 %>">
        <div class="step-marker">3</div>
        <div class="step-details">
          <p class="step-title">お仕事の内容</p>
        </div>
      </div>
      <div class="step-item <%= 'is-active' if @step == 4 %> <%= 'is-completed' if @step > 4 %>">
        <div class="step-marker">4</div>
        <div class="step-details">
          <p class="step-title">写真</p>
        </div>
      </div>
      <div class="step-item <%= 'is-active' if @step == 5 %> <%= 'is-completed' if @step > 5 %>">
        <div class="step-marker">5</div>
        <div class="step-details">
          <p class="step-title">公開</p>
        </div>
      </div>

      <!-- お仕事登録フォーム-->
      <%= form_for @gig, html: {class: "steps-content m-l-100 m-r-100"} do |f| %>
        <%= hidden_field_tag 'step', @step %>
        
        <%= render 'step1', f: f %>
        <%= render 'step2', f: f %>
        <%= render 'step3', f: f %>
        <%= render 'step4', f: f %>
        <%= render 'step5', f: f %>

      <% end %>
    </div>
  </div>
</section>



「app\controllers\gigs_controller.rb」ファイルに以下の記述を追加します。


記述追加 app\controllers\gigs_controller.rb(22行目)

  def edit
    @categories = Category.all
    @step = params[:step].to_i
  end



app\controllers\gigs_controller.rb

class GigsController < ApplicationController
 
  before_action :authenticate_user!, except: [:show]
  before_action :set_gig, except: [:new, :create]
  before_action :is_authorised, only: [:edit, :update, :upload_photo, :delete_photo]

  def new
    @gig = current_user.gigs.build
    @categories = Category.all
  end

  def create
    @gig = current_user.gigs.build(gig_params)
    if @gig.save
      @gig.pricings.create(Pricing.pricing_types.values.map{ |x| {pricing_type: x} })
      redirect_to edit_gig_path(@gig), notice: "保存しました"
    else
      redirect_to request.referrer, flash: { error: @gig.errors.full_messages }
    end
  end

  def edit
    @categories = Category.all
    @step = params[:step].to_i
  end

  def update
  end

  def show
  end

  def upload_photo
  end

  def delete_photo
  end

  private

  def set_step
    @step = params[:step].to_i > 0 ? params[:step].to_i : 1
    if @step > 5
      @step = 5
    end
  end

  def set_gig
    @gig = Gig.find(params[:id])
  end

  def is_authorised
    redirect_to root_path, alert: "あなたには権限がありません。" unless current_user.id == @gig.user_id
  end

  def gig_params
    params.require(:gig).permit(:title, :video, :description, :active, :category_id, :has_single_pricing, 
                                pricings_attributes: [:id, :title, :description, :delivery_time, :price, :pricing_type])
  end
  
end



「app\views\gigs」フォルダに次の5つの新規ファイルを作成します。

  • 「_step1.html.erb」
  • 「_step2.html.erb」
  • 「_step3.html.erb」
  • 「_step4.html.erb」
  • 「_step5.html.erb」



app\views\gigs\_step1.html.erb(新規作成したファイル)

<div class="step-content <%= 'is-active' if @step == 1 %>">
    <div class="field">
        <label class="label">お仕事のタイトル</label>
        <%= f.text_area :title, autocomplete: "title", class: "textarea" %>
    </div>
    <div class="field">
        <label class="label">カテゴリー</label>
        <%= f.select(:category_id, options_for_select(@categories.map{ |c| [c.name, c.id] }, selected: @gig.category_id)) %>
    </div>
    <div class="field">
        <label class="checkbox">
            <%= f.check_box :has_single_pricing, class: "checkbox", onchange: "this.form.submit();" %> シングルプランの場合にチェック
        </label>
    </div>
</div>



app\views\gigs\_step2.html.erb(新規作成したファイル)

<div class="step-content <%= 'is-active' if @step == 2 %>">
    <div class="field">
        <div class="control">
            <div class="columns has-text-centered">

                <%= f.fields_for :pricings, @gig.pricings.order(:pricing_type) do |p| %>
                    <div class="column <%= 'is-4 is-offset-4' if @gig.has_single_pricing && p.object.basic? %>
                                      <%= 'is-hidden' if @gig.has_single_pricing && !p.object.basic? %> ">
                        <label for="" class="label">
                            <% if p.object.basic? %>
                                ベーシック
                            <% elsif p.object.standard? %>
                                スタンダード
                            <% else %>
                                プレミアム
                            <% end %>
                        </label>
                        <%= p.hidden_field :pricing_type %>

                        <div class="control">
                            <%= p.text_field :title, placeholder: "タイトル", class: "input is-radiusless" %>
                        </div>

                        <div class="control">
                            <%= p.text_area :description, placeholder: "詳細", class: "textarea is-radiusless" %>
                        </div>

                        <div class="control has-icons-right">
                            <%= p.number_field :delivery_time, placeholder: "期日", class: "input is-radiusless", default: 1 %>
                            <span class="icon is-small is-right"></span>
                        </div>

                        <div class="control has-icons-right">
                            <%= p.number_field :price, placeholder: "価格", class: "input is-radiusless", default: 1 %>
                            <span class="icon is-small is-right"></span>
                        </div>

                    </div>
                <% end %>

            </div>
        </div>
    </div>
</div>


app\views\gigs\_step3.html.erb(新規作成したファイル)

<div class="step-content <%= 'is-active' if @step == 3 %>">
    <div class="field">
        <label for="" class="label">お仕事の内容</label>
        <%= f.rich_text_area :description, rows: 50, cols: 50 %>
    </div>
</div>


app\views\gigs\_step4.html.erb(新規作成したファイル)

<div class="step-content <%= 'is-active' if @step == 4 %>">
    <div class="field">
        <label for="" class="label">Youtubeコード</label>
        <%= f.text_field :video, autocomplete: "YoutubeのURI", class: "input" %>
    </div>

    <div class="field">
        <label for="" class="label">写真をアップロード</label>
        <div class="control">
            <div class="m-b-20">
                <div class="dropzone" id="myDropzone"  style="height: 200px;" action="/gigs/<%= @gig.id %>/upload_photo"></div>
            </div>

            <div class="columns is-multiline" style: width: 100%%>
                <% @gig.photos.each do |photo| %>
                    <div class="column is-one-fifth">
                        <div class="card is-image">
                            <div class="card-image">
                                <%= link_to 'Remove', delete_photo_gig_url(photo_id: photo.id, id: @gig.id, step: @step), 
                                        method: :delete,
                                        data: { confirm: "削除して本当によろしいですか?" },
                                        class: "delete delete-file is-pulled-right",
                                        style: "z-index: 100"  %>

                                <figure class="image is-4by3">
                                    <%= image_tag url_for(photo) %>
                                </figure>
                            </div>
                        </div>
                    </div>

                <% end %>
            </div>
        </div>
    </div>
</div>

<script>
    Dropzone.options.myDropzone = {
        paramName: "file",
        maxFilesize: 2,
        acceptedFiles: "image/*",
        init: function() {
            this.on('complete', function (file) {
                location.reload();
            })
        }
    }
</script>


app\views\gigs\_step5.html.erb(新規作成したファイル)

<div class="step-content has-text-centered <%= 'is-active' if @step == 5 %>">
    <div>
        <%= hidden_field_tag 'active', 'true' if @step == 5 %>
        <strong class="is-size-2">あともう少し</strong>
        <p>お仕事を公開しましょう</p>
    </div>
</div>

<div class="field is-grouped is-grouped-centered m-t-25">
    <p class="control <%= 'is-hidden' if @step <= 1 %>">
        <%= link_to '戻る', edit_gig_path(@gig, step: @step - 1), class: "button is-light" %>
    </p>

    <p class="control">
        <% if @step != 5 %>
            <%= f.submit '保存して続ける', class: "button is-primary" %>
        <% else %>
            <%= link_to '公開する', gig_path(@gig.id, gig: {active: true}, step: @step), 
                        method: :put, 
                        data: {confirm: "お仕事を公開してよろしいですか?"},
                        class: "button is-danger" %>
        <% end %>
    </p>
</div>



ブラウザ確認
アドレスを順番に入力し、表示されるか確認します。
http://localhost:3000/gigs/new
一度お仕事を新規登録する必要があります。


http://localhost:3000/gigs/1/edit?step=1
http://localhost:3000/gigs/1/edit?step=2
http://localhost:3000/gigs/1/edit?step=3
http://localhost:3000/gigs/1/edit?step=4
http://localhost:3000/gigs/1/edit?step=5


「app\controllers\gigs_controller.rb」ファイルを編集していきます。


1.25行目の「@step = params[:step].to_i」の記述を削除します。


2.6行目に「before_action :set_step, only: [:update, :edit]」の記述を追加します。


3.28行目の「update()」メソッドを以下のように編集します。

  def update

    if @step == 2
      gig_params[:pricings_attributes].each do |index, pricing|
        if @gig.has_single_pricing && pricing[:pricing_type] != Pricing.pricing_types.key(0)
          next;
        else
          if pricing[:title].blank? || pricing[:description].blank? || pricing[:delivery_time].blank? || pricing[:price].blank?
            return redirect_to request.referrer, flash: {error: "価格が無効です"}
          end
        end
      end
    end

    if @step == 3 && gig_params[:description].blank?
      return redirect_to request.referrer, flash: {error: "詳細を空白にすることはできません"}
    end

    if @step == 4 && @gig.photos.blank?
      return redirect_to request.referrer, flash: {error: "写真がありません"}
    end

    if @step == 5
      @gig.pricings.each do |pricing|
        if @gig.has_single_pricing && !pricing.basic?
          next;
        else
          if pricing[:title].blank? || pricing[:description].blank? || pricing[:delivery_time].blank? || pricing[:price].blank?
            return redirect_to edit_gig_path(@gig, step: 2), flash: {error: "価格が無効です"}
          end
        end
      end

      if @gig.description.blank?
        return redirect_to edit_gig_path(@gig, step: 3), flash: {error: "詳細を空白にすることはできません"}
      elsif @gig.photos.blank?
        return redirect_to edit_gig_path(@gig, step: 4), flash: {error: "写真がありません"}
      end
    end

    if @gig.update(gig_params)
      flash[:notice] = "保存しました"
    else
      return redirect_to request.referrer, flash: {error: @gig.errors.full_messages}
    end

    if @step < 5
      redirect_to edit_gig_path(@gig, step: @step + 1)
    else
      redirect_to dashboard_path
    end

  end



記述更新 app\controllers\gigs_controller.rb
変更箇所が多いのでコードをコピーしてファイルの内容を置き換えてください。

class GigsController < ApplicationController
 
  before_action :authenticate_user!, except: [:show]
  before_action :set_gig, except: [:new, :create]
  before_action :is_authorised, only: [:edit, :update, :upload_photo, :delete_photo]
  before_action :set_step, only: [:update, :edit]

  def new
    @gig = current_user.gigs.build
    @categories = Category.all
  end

  def create
    @gig = current_user.gigs.build(gig_params)

    if @gig.save
      @gig.pricings.create(Pricing.pricing_types.values.map{ |x| {pricing_type: x} })
      redirect_to edit_gig_path(@gig), notice: "保存しました"
    else
      redirect_to request.referrer, flash: { error: @gig.errors.full_messages }
    end
  end

  def edit
    @categories = Category.all
  end

  def update

    if @step == 2
      gig_params[:pricings_attributes].each do |index, pricing|
        if @gig.has_single_pricing && pricing[:pricing_type] != Pricing.pricing_types.key(0)
          next;
        else
          if pricing[:title].blank? || pricing[:description].blank? || pricing[:delivery_time].blank? || pricing[:price].blank?
            return redirect_to request.referrer, flash: {error: "価格が無効です"}
          end
        end
      end
    end

    if @step == 3 && gig_params[:description].blank?
      return redirect_to request.referrer, flash: {error: "詳細を空白にすることはできません"}
    end

    if @step == 4 && @gig.photos.blank?
      return redirect_to request.referrer, flash: {error: "写真がありません"}
    end

    if @step == 5
      @gig.pricings.each do |pricing|
        if @gig.has_single_pricing && !pricing.basic?
          next;
        else
          if pricing[:title].blank? || pricing[:description].blank? || pricing[:delivery_time].blank? || pricing[:price].blank?
            return redirect_to edit_gig_path(@gig, step: 2), flash: {error: "価格が無効です"}
          end
        end
      end

      if @gig.description.blank?
        return redirect_to edit_gig_path(@gig, step: 3), flash: {error: "詳細を空白にすることはできません"}
      elsif @gig.photos.blank?
        return redirect_to edit_gig_path(@gig, step: 4), flash: {error: "写真がありません"}
      end
    end

    if @gig.update(gig_params)
      flash[:notice] = "保存しました"
    else
      return redirect_to request.referrer, flash: {error: @gig.errors.full_messages}
    end

    if @step < 5
      redirect_to edit_gig_path(@gig, step: @step + 1)
    else
      redirect_to dashboard_path
    end

  end

  def show
  end

  def upload_photo

  end

  def delete_photo

  end

  private

  def set_step
    @step = params[:step].to_i > 0 ? params[:step].to_i : 1
    if @step > 5
      @step = 5
    end
  end

  def set_gig
    @gig = Gig.find(params[:id])
  end

  def is_authorised
    redirect_to root_path, alert: "あなたには権限がありません。" unless current_user.id == @gig.user_id
  end

  def gig_params
    params.require(:gig).permit(:title, :video, :description, :active, :category_id, :has_single_pricing, 
                                pricings_attributes: [:id, :title, :description, :delivery_time, :price, :pricing_type])
  end
end



↓↓クリックして頂けると励みになります。


[21]仕事ビュー << [ホームに戻る] >> [23]dropzone