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?

【Rails】商品情報編集機能の実装

Last updated at Posted at 2026-01-14

Rails学習における「編集機能(edit/update)」の実装を通じて、MVCがどのようにバトンを繋ぎ、データの正確性を守っているのかを深く掘り下げます。

  1. 実装の全体像(What)と具体的なコード解説
    商品編集機能は、以下の4つの要素が連携して完成します。

① ルーティング:リクエストの「入り口」
ファイル: config/routes.rb

# edit(表示)と update(更新)アクションへのパスを生成
resources :items, only: [:index, :new, :create, :show, :edit, :update]

Railsの「地図」を広げる作業です。URL(/items/:id/edit)と、動かすべきコントローラーのアクションを紐付けます。これがないと「No Route Error」が発生します。

② コントローラー:現場の司令塔とガードマン
ファイル: app/controllers/items_controller.rb

class ItemsController < ApplicationController
  #1. 前処理(フィルタ)で安全性を確保
  before_action :authenticate_user!, only: [:edit, :update]
  before_action :set_item, only: [:show, :edit, :update]
  before_action :move_to_index, only: [:edit, :update]

  def update
    # 2. updateメソッドを呼んだ瞬間にモデルのバリデーションが走る
    if @item.update(item_params)
      redirect_to item_path(@item.id) # 成功:詳細ページへ
    else
      # 失敗:入力内容を保持して編集画面を再表示
      render :edit, status: :unprocessable_entity 
    end
  end

  private
  def set_item
    @item = Item.find(params[:id])
  end

  def move_to_index
    # 出品者本人以外がアクセスしてきたらトップページへリダイレクト
    redirect_to root_path unless current_user.id == @item.user_id
  end
end

なぜ before_action で本人確認をするのか?

ビューで編集ボタンを非表示にするだけでは、URL(/items/商品ID/edit)を直接入力する「URL直打ち」の攻撃を防げません。サーバーサイドの入り口で物理的にアクセスを遮断することで、他人の商品データを改ざんされるリスクを根本から排除しています。

なぜ保存失敗時に render :edit を使うのか?

redirect_to(新しいリクエストを送り直す)を使うと、ユーザーがせっかく入力した内容が消えてしまいます。 render を使えば、入力途中のデータ(@itemの中身)を保持したまま画面を表示できるため、ユーザーは間違った箇所だけを直すことができ、UX(ユーザー体験)が向上します。

③ モデル:データの正確性を守る「番人」
ファイル: app/models/item.rb

# データの正しさを判定する
validates :name, :info, :price, :image, presence: true
validates :price, numericality: { only_integer: true, greater_than_or_equal_to: 300 }

バリデーションは、不適切なデータをDBに入れないための最終防衛ラインです。保存・更新の直前に自動で発動し、ルール違反があればエラーメッセージを生成します。

④ ビュー:ユーザーへの「窓口」と「hoge」の解消
ファイル: app/views/items/edit.html.erb

<%= form_with model: @item, local: true do |f| %>
  <%# エラー理由を表示し、ユーザーに修正を促す %>
  <%= render 'shared/error_messages', model: f.object %>

  <%# 仮名「hoge」を実際のカラム名(:name等)に書き換える %>
  <%= f.text_area :name, class:"items-text" %>
  ...
<% end %>

なぜ「hoge」をカラム名に書き換えるのか?

テンプレートにある :hoge は単なる目印です。これを :name や :price に書き換えることで、Railsの**「データバインディング」**が機能します。

初期値の表示: form_with がモデルオブジェクトから値を自動抽出し、編集画面を開いた瞬間に「以前入力した内容」を表示してくれます。

更新の正確性: 入力された値がどのカラム(名前なのか、価格なのか)に対応するかをRailsが正しく認識できるようになります。

0
0
0

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?