PROGRAMMING

RailsでECサイトを作る!【商品をカートに追加する】





初めての投稿ですが、今回は商品をカートに追加する作業をしていきたいと思います!

今回やること
・UserにCartを紐付けさせる
・CartとProductsを紐付けさせる
・Userは自分のCartの中身を確認できるようにする

こんな感じで今回はやっていきたいと思います!

参考にした記事

・こちらのページを参考にさせて頂きました!

作成手順

モデル作り

$rails g model Cart user:references
$rails g model CartProduct product:references cart:references

まずは上記のようにモデルを作っていきます!

前提として

  • Productは商品のモデルで、商品名と価格と詳細、画像のカラムが入っています。
  • Cartは商品カートのモデル。
  • Cart_Productsはカートに貼っている商品のモデル。CartProductsの中間テーブルになり、多対多の関係になる。
class CreateCarts < ActiveRecord::Migration[5.2]
  def change
    create_table :carts do |t|
      t.references :user, foreign_key: true

      t.timestamps
    end
  end
end

class CreateCartProducts < ActiveRecord::Migration[5.2]
  def change
    create_table :cart_products do |t|
      t.references :product, foreign_key: true
      t.references :cart, foreign_key: true

      t.timestamps
    end
  end
end
$ rails db:migrate

マイグレーションは忘れずに実行。

class User < ApplicationRecord
  has_many :products
  has_one :cart, dependent: :destroy
end

class Product < ApplicationRecord
   has_many :cart_products, dependent: :destroy
end

class Cart < ApplicationRecord
  belongs_to :user
  has_many :cart_products,dependent: :destroy
  has_many :products, through: :cart_products
end 

class CartProduct < ApplicationRecord
  belongs_to :product
  belongs_to :cart
end
  • UserCarthas_oneで紐付け ・has_manyproductcartcartproductを紐付け

ルーティング設定

resources :products, only: [:new,:show,:create] do
   scope module: :products do
      resources :add_to_carts, only: [:create]
      resources :delete_in_carts, only: [:create]
   end
end
    
resource :cart, only: [:show]
  • product_id を取得しないと買い物かごにどのproductが入るかわからないので、パラメーターにproduct_idが入るように設定。
app/controllers/products/add_to_carts_controller.rb
app/controllers/products/delete_in_carts_controller.rb

上記のようにproductsのディレクトリ配下にcontrollerをまとめたいので、下記のようにscopeというものを追加して管理しました。




scope module: :products do
end




コントローラーの作成

それでは、コントローラーを作成していきます。

  • productsディレクトリを作成。app/controllers/products
  • app/controllers/products/application_controller.rb
  • app/controllers/products/add_to_carts_controller.rb
  • app/controllers/products/delete_in_carts_controller.rbの3つを作成。
class Products::AddToCartsController < Products::ApplicationController
    def create
      cart = current_user.prepare_cart
      product = Product.find(params[:product_id])
      cart.cart_products.create!(product_id: product.id)
      redirect_to cart_path
    end
end

カートのデータが作成されていないため、カート自体を作成する必要があります。カートがない時はカートを作成して取得し、すでに作成されていれば作成する必要はありません。

user.rbにprepare_cartというメソッドを定義してあげます。

class User < ApplicationRecord

def prepare_cart
   cart || create_cart
end
class Products::AddToCartsController < Products::ApplicationController
    def create
      cart = current_user.prepare_cart
      product = Product.find(params[:product_id])
      cart.cart_products.create!(product_id: product.id)
      redirect_to cart_path
    end
end
上記の内容:
  • current_user.cartがnilの場合は、カートが作成される
  • productのidを取得
  • cart_productsのなかにproduct_idを保存する
  • 実行後カートの中身へリダイレクト
$rails g controller carts show

カートの中身を見れるように、cartsのcontrollerを作成。

class CartsController < ApplicationController
  before_action :authenticate_user!
  
  def show
    cart = current_user.prepare_cart
    @product = cart.products
  end
end

カートの中身を確認できるようにしました!

  • authenticate_user!メソッドでログインしていない場合は買い物かごに追加できない、買い物かごの内容も確認できないようにする。※authenticate_user!はdeviseによって提供されているメソッドです。
  • current_userからcartを取得し、cartからproductの一覧を取得。
class Products::DeleteInCartsController < Products::ApplicationController
    
    def create
        cart = current_user.prepare_cart
        product = Product.find(params[:product_id])
        
        cart_product = cart.cart_products.find_by(product_id: product.id)
        cart_product.destroy
        redirect_to cart_path
    end
end

カートの中のproductsを削除できるようにしました!

  • current_userからcartを取得。
  • product_idからproductを取得
  • cartの中に入っているproductを探し、cartからproductを削除。
  • 削除後はカートの中身へリダイレクト
class Products::ApplicationController < ApplicationController
    before_action :authenticate_user!
end

productのカートへの追加と削除をログイン状態でないと出来ないようにProducts::ApplicationControllerにauthenticate_user!を追加!

ビューの作成

<div class='container'>
    <div class ='header-cart'>
        <h1 class='text-center mb-50'>カートの中身</h1>
    </div>
    <ul class='list-group'>
        <% @product.each do |product| %>
        <li class='list-group-product d-flex justify-content-between border p-3'>
        <p><%= product.name %></p>
        <span><%= product.price %>円 <a><%= link_to '×',product_delete_in_carts_path(product), method: :post, data: {confirm: '削除してもいいですか?'} %></a></span>
        </li>
        <% end %>
    </ul>
</div>

無事にカートに商品と価格、削除ボタンが入りました!

削除ボタンを押すと実際に商品が消えることを確認しました。

まとめ

今回は商品をカートに追加する機能をつけてみました。

次回は決済機能の追加をしていきたいと思います!

今後もこんな感じで自分が取り組んでいるプログラミングの内容を定期的にアップしていこうと思いますので、よろしくお願い致します。

最後まで読んでいただきありがとうございました!

-PROGRAMMING

Copyright © Iseblog ,@2020 All Rights Reserved.