【Rails】リンクのpathを条件付きにする

Ruby on Railsアイキャッチ画像

前回の、こちらの続きのような内容になっています。

CRUDに画像表示欄を追加し、且つ、ページリンクの条件分岐方法についてまとめています。

変更ファイル

変更を加えたファイルはこちらの6つです。

views/customers/show.html.erb

views/customer_documents/index.html.erb

views/customer_documents/show.html.erb

views/customer_documents/new.html.erb

views/customer_documents/edit.html.erb

controllers/customer_documents_controller.rb

views

まずは、ネストしたCRUDの親の詳細ページから。

リンクが押されたときに、params{ “general”: “true” }やparams{ “technical”: “true” }といったパラメータが送られるようにすることで、controllerで条件分岐ができるようにする。

<!-- <%= link_to '資料', customer_customer_documents_path(@customer.id) %> -->
<%= link_to '一般資料', customer_customer_documents_path(@customer.id, general: "true") %>
<%= link_to '技術資料', customer_customer_documents_path(@customer.id, technical: "true") %>

index

以下内容を変更する。

  • documentの欄を追加
  • generalとtechnicalで、同じフォームを使用できるよう、インスタンス変数を@documentに統一

変更前

<h1>Customer Documents</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Content</th>
      <th>Public level</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @customer_documents.each do |customer_document| %>
      <tr>
        <td><%= customer_document.name %></td>
        <td><%= customer_document.content %></td>
        <td>
        <% if customer_document.public_level == 0 %>一般
        <% elsif customer_document.public_level == 1 %>技術
        <% end %>
        </td>
        <td><%= link_to 'Show', customer_customer_document_path(@customer, customer_document) %></td>
        <td><%= link_to 'Edit', edit_customer_customer_document_path(@customer, customer_document) %></td>
        <td><%= link_to 'Destroy', customer_customer_document_path(@customer, customer_document), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Customer Document', new_customer_customer_document_path %>

変更後

<h1>Customer Documents</h1>

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Content</th>
      <th>Public level</th>
      <!--Documentカラム追加-->
      <th colspan="3">Document</th>
    </tr>
  </thead>

  <tbody>
    <!--customer_documentを全てdocumentに変更-->
    <% @documents.each do |document| %>
      <tr>
        <td><%= document.name %></td>
        <td><%= document.content %></td>
        <td>
        <% if document.public_level == 0 %>一般
        <% elsif document.public_level == 1 %>技術
        <% end %>
        </td>
        <!--前のdocumentが変数で後ろのdocumentがuploader-->
        <td><object data="<%= document.document.url %>" type="application/pdf" ></object></td>
        <td><%= link_to 'Show', customer_customer_document_path(@customer, document) %></td>
        <td><%= link_to 'Edit', edit_customer_customer_document_path(@customer, document) %></td>
        <td><%= link_to 'Destroy', customer_customer_document_path(@customer, document), method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Customer Document', new_customer_customer_document_path %>
<br>
<%= link_to '一覧へ', customer_path(@customer.id) %>

show

こちらは、上記で追加したパラメータを使用して、現在開いているviewから、戻るページを条件分岐する。

変更前

<%= link_to 'Back', customer_customer_documents_path %>

変更後

<% if @product_document.public_level == 0 %>
<%= link_to '一般資料一覧へ', product_product_documents_path(general: "true") %>
<% elsif @product_document.public_level == 1 %>
<%= link_to '技術資料一覧へ', product_product_documents_path(technical: "true") %>
<% end %>

newとedit

これらは、末端のリンク先のため、:backで簡単に戻るようにする。

変更前

<%= link_to 'Back', customer_customer_documents_path %>

変更後

<%= link_to 'Back', :back %>

controller

indexとdestroyに、public_lebelによる条件分岐を追加

class CustomerDocumentsController < ApplicationController
  before_action :set_customer_document, only: %i[show edit update destroy]

  def index
    @customer = Customer.where(id: params[:customer_id]).first
    @customer_documents = @customer.customer_documents.all
  end

  def show; end

  def new
    @customer = Customer.where(id: params[:customer_id]).first
    @customer_document = @customer.customer_documents.build
  end

  def edit; end

  def create
    @customer = Customer.where(id: params[:customer_id]).first
    @customer_document = @customer.customer_documents.build(customer_document_params)
    @customer_document.user_id = current_user.id

    respond_to do |format|
      if @customer_document.save
        format.html { redirect_to [@customer, @customer_document], notice: "Customer document was successfully created." }
        format.html { redirect_to @customer_document, notice: "Customer document was successfully created." }
        format.json { render :show, status: :created, location: @customer_document }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @customer_document.errors, status: :unprocessable_entity }
      end
    end
  end

  def update
    respond_to do |format|
      if @customer_document.update(customer_document_params)
        format.html { redirect_to [@customer, @customer_document], notice: "Customer document was successfully updated." }
        format.json { render :show, status: :ok, location: @customer_document }
      else
        format.html { render :edit, status: :unprocessable_entity }
        format.json { render json: @customer_document.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @customer_document.destroy
    respond_to do |format|
      format.html { redirect_to customer_customer_documents_url, notice: "Customer document was successfully destroyed." }
      format.json { head :no_content }
    end
  end

  private

  def set_customer_document
    @customer = Customer.where(id: params[:customer_id]).first
    @customer_document = @customer.customer_documents.where(id: params[:id]).first
  end

  def customer_document_params
    params.require(:customer_document).permit(:name, :content, :public_level, :user_id, :customer_id, :document, :document_cache)
  end
end

変更後

変更部のアクションのみ記述

  def index
    @customer = Customer.where(id: params[:customer_id]).first
    @customer_documents = @customer.customer_documents.all
    if params[:general]
      @documents = @customer_documents.where(public_level: 0)
    elsif params[:technical]
      @documents = @customer_documents.where(public_level: 1)
    end
  end


  def destroy
    @customer_document.destroy
    respond_to do |format|
      if @customer_document.public_level == 0
        format.html { redirect_to customer_customer_documents_path(general: "true"), notice: "Customer document was successfully destroyed." }
        format.json { head :no_content }
      elsif @customer_document.public_level == 1
        format.html { redirect_to customer_customer_documents_path(technical: "true"), notice: "Customer document was successfully destroyed." }
        format.json { head :no_content }
      end
    end
  end

コメント