【rails】他テーブルのDBの情報をビューで表示させる


はじめに

 この記事は、学んだことを復習するために投稿者が理解できる言葉まで落とし込んで書いております。まだまだ初心者ですが、この記事が読んでくださった方の悩みが解決すれば嬉しいです。

1.結論

  1. アソシエーションが定義されていること
  2. ルーティングが入れ子構造(ネスト)になっていること
  3. 表示させたい側のコントローラーで値を取得していること
  4. ビューで表示させる記述がなされていること

2.コード

2-1.テーブル

  • itemsテーブル
class CreateItems < ActiveRecord::Migration[6.0]
  def change
    create_table :items do |t|
      t.string     :name               , null: false # 商品名
      t.text       :explanation        , null: false # 商品の説明
      t.integer    :category_id        , null: false # カテゴリー
      t.integer    :status_id          , null: false # 商品の状態
      t.integer    :delivery_fee_id    , null: false # 配送料の負担
      t.integer    :shipping_region_id , null: false # 発送地域
      t.integer    :shipping_day_id    , null: false # 発送までの日数
      t.integer    :selling_price      , null: false # 販売価格
      t.references :user               , null: false, foreign_key: true  # 外部キー(user情報)
      t.timestamps
    end
  end
end
  • ordersテーブル
class CreateOrders < ActiveRecord::Migration[6.0]
  def change
    create_table :orders do |t|
      t.references :user, null: false, foreign_key: true # 外部キー(ユーザー情報)
      t.references :item, null: false, foreign_key: true# 外部キー(商品情報)
      t.timestamps
    end
  end
end

2-2.モデル

  • itemモデル
class Item < ApplicationRecord
  belongs_to :user
  has_one :order # ポイント①
  has_one_attached :image

  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :category
  belongs_to_active_hash :status
  belongs_to_active_hash :delivery_fee
  belongs_to_active_hash :shipping_region
  belongs_to_active_hash :shipping_day

  # 共通で、空の投稿を保存できないようにする
  with_options presence: true do
    validates :image
    validates :name
    validates :explanation
    validates :selling_price
  end

  # 共通で、選択が「---」の時は保存できないようにする
  with_options numericality: { other_than: 1 } do
    validates :category_id
    validates :status_id
    validates :delivery_fee_id
    validates :shipping_region_id
    validates :shipping_day_id
  end

  # 販売価格の範囲が、¥300以上~¥9,999,999未満であること
  validates :selling_price, numericality: { greater_than_or_equal_to: 300, less_than_or_equal_to: 9_999_999 }

  # 販売価格は半角数字のみ入力可能
  VALID_DELIVERY_FEE_REGEX = /[0-9\d]/.freeze
  validates :selling_price, format: { with: VALID_DELIVERY_FEE_REGEX }
end

  • orderモデル
class Order < ApplicationRecord
  belongs_to :user
  belongs_to :item # ポイント①
  has_one :address
end

2-3.ルーティング

Rails.application.routes.draw do
  devise_for :users
  root 'items#index'
  resources :items do
    resources :orders, only:[:index, :create]
  end
end

ターミナルで確認します。

アソシエーション先のレコードのidをparamsに追加してコントローラーに送るためにルーティングのネストを使用します。

2-4.コントトーラー

class OrdersController < ApplicationController
  def index
    @item = Item.find(params[:item_id])
  end
end

コントローラーですでに保存してある商品情報を、Item.find(params[:item_id])で取得し、@itemに代入します。

2-5.ビュー

@item.表示したいカラム名

# 上記のように記述することで、他テーブル(items)の情報をビューで表示させることが可能です。

app/views/orders/index.html.erb/

    <div class='buy-item-info'>
      <%= image_tag @item.image, class: 'buy-item-img' %>
      <div class='buy-item-right-content'>
        <h2 class='buy-item-text'>
          <%= @item.explanation %>
        </h2>
        <div class='buy-item-price'>
          <p class='item-price-text'>¥<%= @item.selling_price %></p>
          <p class='item-price-sub-text'>(税込)<%= @item.delivery_fee.name %></p>
        </div>
      </div>
    </div>

以上です。