0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

商品投稿 enum

Last updated at Posted at 2023-07-19

はじめに

:shamrock:管理者側から商品を投稿して顧客の商品一覧ページに表示させます。

ステータスはenumで実装しました。
bootstrap導入済み
devaice導入済み


migrateファイルはこんな感じ

class CreateItems < ActiveRecord::Migration[6.1]
  def change
    create_table :items do |t|
      t.string :name, null: false
      t.text :description, null: false
      t.integer :price, null: false
      t.boolean :is_active, null: false, default: true
      t.timestamps
    end
  end
end

:shamrock:モデルの設定

item.rb
class Item < ApplicationRecord
  has_one_attached :image
 enum status: { on_sale: 0, off_sale: 1 }
end

:star:has_one_attached :image
は、Active Storage(Railsのファイルアップロードを担当する部分)に対する指示で、各Itemレコードが一つのimageファイルを持つことを示しています。

:star:enum status: { on_sale: 0, off_sale: 1 }
は、statusという名前の列があることを示しています。status列は整数型で、on_saleが0、off_saleが1としてマッピングされます。これにより、Itemの状態を文字列ではなく整数でデータベースに保存でき、それによりパフォーマンスを向上させ、コード内で直感的にその状態を理解できます。

:shamrock:コントローラの設定

admin/items/controller.rb
class Admin::ItemsController < ApplicationController
  def new
    @item = Item.new
  end

  def create
    @item = Item.new(item_params)
    if @item.save
      redirect_to admin_items_path
    else
      render :new
    end
  end

  private

  def item_params
    params.require(:item).permit(:name, :description, :price, :status, :image)
  end
end

:star:newアクション
新規Itemオブジェクトを作成し、それを@itemというインスタンス変数に代入します。このアクションは、新規作成フォームの表示を担当します。

:star:createアクション
フォームからのデータ(パラメータ)を用いて新規Itemオブジェクトを作成します。作成が成功した場合、商品一覧ページ(admin_items_path)にリダイレクトします。失敗した場合は、新規作成フォームを再度表示します。

:star:item_params
ストロングパラメータ(Strong Parameters)と呼ばれる機能を使用して、フォームから送信されたデータのうち、どのデータを許可するか(受け取るか)を指定しています。これは、不正なデータを防ぐためのセキュリティ機能です。

:star:private
は、その下に定義されたメソッドがプライベート(このクラスの内部からのみアクセス可能)であることを示します。これにより、他の部分から直接これらのメソッドを呼び出すことはできません。

veiws 商品投稿ページ

admin/items/new.haml.erb
<h3 class="text-center">商品新規登録</h3>
<%= form_with model: [:admin, @item], local: true, class: 'col-6 mx-auto' do |f| %>
  <div class="form-group row">
    <%= f.label :image, '商品画像', class: 'col-sm-3 col-form-label' %>
    <div class="col-sm-9">
      <%= f.file_field :image, class: 'form-control' %>
    </div>
  </div>
  <div class="form-group row">
    <%= f.label :name, '商品名', class: 'col-sm-3 col-form-label' %>
    <div class="col-sm-9">
      <%= f.text_field :name, class: 'form-control' %>
    </div>
  </div>
  <div class="form-group row">
    <%= f.label :description, '商品説明', class: 'col-sm-3 col-form-label' %>
    <div class="col-sm-9">
      <%= f.text_area :description, class: 'form-control' %>
    </div>
  </div>
  <div class="form-group row">
    <%= f.label :price, '税抜価格', class: 'col-sm-3 col-form-label' %>
    <div class="col-sm-9 input-group">
      <%= f.number_field :price, class: 'form-control' %>
      <div class="input-group-append">
        <span class="input-group-text"></span>
      </div>
    </div>
  </div>
  
  <div class="form-group row">
  <%= f.label :status, '販売ステータス', class: 'col-sm-3 col-form-label' %>
  <div class="col-sm-9">
    <div class="custom-control custom-radio custom-control-inline">
      <%= f.radio_button :status, 'on_sale', checked: @item.status == 'on_sale', class: 'custom-control-input', id: 'status-on-sale' %>
      <%= f.label :status, '販売中', class: 'custom-control-label', for: 'status-on-sale' %>
    </div>
    <div class="custom-control custom-radio custom-control-inline">
      <%= f.radio_button :status, 'off_sale', checked: @item.status == 'off_sale', class: 'custom-control-input', id: 'status-off-sale' %>
      <%= f.label :status, '販売停止中', class: 'custom-control-label', for: 'status-off-sale' %>
    </div>
  </div>
</div>


  </div>
  <div class="form-group row">
    <div class="col-sm-9 offset-sm-3">
      <%= f.submit '新規投稿', class: 'btn btn-success text-white' %>
    </div>
  </div>
<% end %>

:cherry_blossom:販売ステータスについて

<div class="form-group row">
  <%= f.label :status, '販売ステータス', class: 'col-sm-3 col-form-label' %>
  <div class="col-sm-9">

:star:上記の部分はブートストラップのクラスを使用してレイアウトを作成しています。:statusは商品のステータス(販売中か販売停止中か)を示す属性です。

    <div class="custom-control custom-radio custom-control-inline">
      <%= f.radio_button :status, 'on_sale', checked: @item.status == 'on_sale', class: 'custom-control-input', id: 'status-on-sale' %>
      <%= f.label :status, '販売中', class: 'custom-control-label', for: 'status-on-sale' %>
    </div>

:star:この部分では、on_sale(販売中)というステータスを設定するラジオボタンを作成しています。
@item.status == 'on_sale' という部分は、商品の現在のステータスがon_sale であれば、このラジオボタンが選択されるようにしています。

    <div class="custom-control custom-radio custom-control-inline">
      <%= f.radio_button :status, 'off_sale', checked: @item.status == 'off_sale', class: 'custom-control-input', id: 'status-off-sale' %>
      <%= f.label :status, '販売停止中', class: 'custom-control-label', for: 'status-off-sale' %>
    </div>
  </div>
</div>

:sunny:最後の部分は販売停止(off_sale)のステータスを設定するラジオボタンを作成しています。
@item.status == 'off_sale' という部分は、商品の現在のステータスが off_sale であれば、このラジオボタンが選択されるようにしています。

このように、管理者は商品のステータスを選択して、商品が販売中か販売停止中かを設定することができます。これらの設定はItemモデルの:status属性に保存されます。


補足

以下のエラーが発生したら
image.png

このエラーは、Active Storageが適切にセットアップされていないことを示しています。Active Storageは、Railsでファイルアップロードを処理するためのフレームワークです。具体的には、active_storage_blobsテーブルがデータベースに存在しないために発生しています。
エラーメッセージにあるように、以下のコマンドを実行してActive Storageをセットアップし、必要なテーブルを作成します。

$ bin/rails active_storage:install

このコマンドを実行すると、必要なマイグレーションファイルが作成されます。その後、以下のコマンドを実行してマイグレーションをデータベースに適用します。

$ bin/rails db:migrate

これにより、Active Storageが適切に機能します

完成イメージ
スクリーンショット 2023-07-19 14.50.39.png

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?