Railsで「自転車紹介ページ」を作った話 〜こだわりの1台をアピールせよ〜

プログラミング技術ブログ

こんにちは、もみあげ稲荷です!

今回は、自分のRailsアプリに「自転車紹介ページ」を追加したときの実装記録をまとめました。

このページの目的は、ユーザーが「自分のこだわりの1台」を紹介できるようにすること。
複数台のバイクを持っている人でも、紹介できるのはたった1台だけ。

スペックじゃなく、こだわりで語る世界を目指して実装しました!


🎯 ページの目的と特徴

  • 自転車好きのユーザーが「自慢の1台」を紹介できる
  • 紹介できるのは 1ユーザーにつき1台のみ
  • 写真は1枚だけアップロードできる
  • メーカー名やパーツなどは自由記述(人それぞれのこだわりをアピール)
  • 「この人のこだわり分かる!」みたいな共感を生むページにしたい

🏗 モデル設計

User has_one :bike
Bike belongs_to :user
Bike has_one_attached :image

ActiveStorageを使って画像を1枚だけアップロードできるようにしました。

🧱 マイグレーション

rails g model Bike image:string description:text user:references
rails active_storage:install
rails db:migrate

(※ imageカラムは使わなくなるけど、最初は追加しちゃってたやつ)


🛣 ルーティング

resource :bike  # 単数形!1人1台限定!

ルーティングでは resources ではなく、 resource を使っているのがポイント!
これによって new_bike_pathedit_bike_pathbike_path などが使えるようになります。


🎮 コントローラー

class BikesController < ApplicationController
  before_action :authenticate_user!

  def new
    @bike = current_user.build_bike
  end

  def create
    @bike = current_user.build_bike(bike_params)
    if @bike.save
      redirect_to bike_path, notice: "自転車を登録しました!"
    else
      render :new, status: :unprocessable_entity
    end
  end

  def show
    @bike = current_user.bike
  end

  def edit
    @bike = current_user.bike
  end

  def update
    @bike = current_user.bike
    if @bike.update(bike_params)
      redirect_to bike_path, notice: "更新しました!"
    else
      render :edit, status: :unprocessable_entity
    end
  end

  private

  def bike_params
    params.require(:bike).permit(:image, :description)
  end
end

current_user.build_bikecurrent_user.bike など、単数リソース特有の書き方が登場します!


🧾 ビュー(new / show)

new.html.erb

<%= form_with model: @bike, url: bike_path, local: true do |form| %>
  <% if @bike.errors.any? %>
    <div class="error-messages">
      <ul>
        <% @bike.errors.full_messages.each do |message| %>
          <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <div>
    <%= form.label :image, "自転車の写真" %><br>
    <%= form.file_field :image %>
  </div>

  <div>
    <%= form.label :description, "こだわり・カスタムなど" %><br>
    <%= form.text_area :description, rows: 5 %>
  </div>

  <%= form.submit "登録する!" %>
<% end %>

show.html.erb

<h1>あなたの自慢の1台!</h1>

<% if @bike.image.attached? %>
  <%= image_tag @bike.image, style: "max-width: 400px;" %>
<% end %>

<p><%= simple_format(@bike.description) %></p>

<%= link_to "編集する", edit_bike_path %>

🧠 学びと感想

  • 単数リソース(resource)の使い方を初めて理解できた
  • ActiveStorageは使う前に install & migrate が必要なのをよく忘れる…
  • form_with のルーティング先も自分で指定するのが大事だった!
  • 実装してみると、「この1台にこだわる」っていう文化を表現できて、作ってて楽しかった

明日は、ルートに写真を1枚紐づける「写真機能」についても紹介する予定です!
ここまで読んでくれてありがとう!

コメント

タイトルとURLをコピーしました