rails esサイト カート機能とオーダー機能での不具合
railsは勿論プログラミング初心者です。
今回「Railsによるアジャイルwebアプリケーション開発(第4版)」という本を参考にしてecサイトアプリを作っているのですが、記述通りに作成しているのに不具合が起きて自分では対処できないので質問させていただきました。
手順としましては、簡単な商品投稿と一覧と詳細が見れるサイト作り、カート機能追加し、オーダー機能を追加という感じです。
カート機能追加まではうまくいってたのですが、オーダー機能の追加の際にカートに商品を入れられなくなる現象が起こりました。controllerはapplication,orders,carts,line_items,store,productsの6つ。modelは、order,cart,line_item,productの4つです。問題箇所だと思われる中身を載せてみます
・carts_controller.rb
class CartsController < ApplicationController
# before_action :set_cart, only: [:show, :edit, :update, :destroy]
def index
@carts = Cart.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: @carts }
end
end
def show
begin
@cart = Cart.find(params[:id])
rescue ActiveRecord::RecordNotFound
logger.error "無効なカート#{params[:id]}にアクセスしようとしました"
redirect_to store_url, notice: '無効なカートです'
else
respond_to do |format|
format.html #show.html.erb
format.json { render json: @cart }
end
end
end
def new
@cart = Cart.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @cart }
end
end
def edit
@cart = Cart.find(params[:id])
end
def create
@cart = Cart.new(params[:cart])
respond_to do |format|
if @cart.save
format.html { redirect_to @cart, notice: 'Cart was successfully created.' }
format.json { render json: @cart, status: :created, location: @cart }
else
format.html { render :new }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
def update
@cart = Cart.find(params[:id])
respond_to do |format|
if @cart.update_attributes(params[:cart])
format.html { redirect_to @cart, notice: 'Cart was successfully updated.' }
format.json { head :ok }
else
format.html { render :edit }
format.json { render json: @cart.errors, status: :unprocessable_entity }
end
end
end
def destroy
@cart = current_cart
@cart.destroy
session[:cart_id] = nil
respond_to do |format|
format.html { redirect_to store_url }
format.json { head :ok }
end
end
# private
# def set_cart
# @cart = Cart.find(params[:id])
# end
# def cart_params
# params.fetch(:cart, {})
# end
end
・orders_controller.rb
class OrdersController < ApplicationController
def new
@cart = current_cart
if @cart.line_items.empty?
redirect_to store_url, notice: "カートは空です"
return
end
@order = Order.new
respond_to do |format|
format.html
format.json { render json: @order }
end
end
def create
@order = Order.new(params[:order])
# @order = params[:order].permit(:name, :address, :email, :pay_type)
# Order.new(@order)
@order.add_line_items_from_cart(current_cart)
respond_to do |format|
if @order.save
Cart.destroy(session[:cart_id])
session[:cart_id] = nil
format.html {redirect_to store_url, notice:
'ご注文ありがとうございます^^'}
format.json { render json: @order, status: :created, location: @order}
else
@cart = current_cart
format.html {render action: "new"}
format.json {render json: @order.errors,
status: :unprocessable_entity}
end
end
end
def index
@orders = Order.all
respond_to do |format|
format.html
format.json { render json: @orders }
end
end
def show
@order = Order.find(params[:id])
respond_to do |format|
format.html
format.json { render json: @order }
end
end
def edit
@order = Order.find(params[:id])
end
def update
@order = Order.find(params[:id])
respond_to do |format|
if @order.update_attributes(params[:order])
format.html { redirect_to @order, notice: 'Order was successfully updated.' }
format.json { head :ok }
else
format.html { render action: "edit" }
format.json { render json: @order.errors, status: :unprocessable_entity }
end
end
end
def destroy
@order = Order.find(params[:id])
@order.destroy
respond_to do |format|
format.html { redirect_to orders_url }
format.json { head :ok }
end
end
end
・line_items_controller.rb
class LineItemsController < ApplicationController
before_action :set_line_item, only: [:show, :edit, :update, :destroy]
def index
@line_items = LineItem.all
end
def show
@line_item = LineItem.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @line_item }
end
end
def new
@line_item = LineItem.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: @line_item }
end
end
def edit
@line_item = LineItem.find(params[:id])
end
def create
@cart = current_cart
product = Product.find(params[:product_id])
@line_item = @cart.add_product(product.id)
respond_to do |format|
if @line_item.save
# format.html { redirect_to store_url, notice: 'Line item was successfully created.' }
format.html { redirect_to store_url}
format.js { @current_item = @line_item}
format.json { render json: @line_item, status: :created, location: @line_item }
else
format.html { render action: "new" }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
def update
@line_item = LineItem.find(params[:id])
respond_to do |format|
if @line_item.update(line_item_params)
format.html { redirect_to @line_item, notice: 'Line item was successfully updated.' }
format.json { render :show, status: :ok, location: @line_item }
else
format.html { render :edit }
format.json { render json: @line_item.errors, status: :unprocessable_entity }
end
end
end
def destroy
@line_item = LineItem.find(params[:id])
@line_item.destroy
respond_to do |format|
format.html { redirect_to store_url, notice: 'Line item was successfully destroyed.' }
format.json { head :no_content }
end
end
def decrease
@cart = current_cart
@line_item = @cart.decrease(params[:id])
respond_to do |format|
if @line_item.save
format.html{redirect_to store_url}
format.json{head :ok}
else
format.html{render action: "edit"}
format.json{render json: @line_item.errors, status: :unprocessable_entity}
end
end
end
def increase
@cart = current_cart
@line_item = @cart.increase(params[:id])
respond_to do |format|
if @line_item.save
format.html{redirect_to store_url}
format.json{head :ok}
else
format.html{render action: "edit"}
format.json{render json: @line_item.errors, status: :unprocessable_entity}
end
end
end
private
def set_line_item
@line_item = LineItem.find(params[:id])
end
def line_item_params
params.fetch(:line_item, {})
end
end
・cart.rb
class Cart < ApplicationRecord
has_many :line_items, dependent: :destroy
def add_product(product_id)
current_item = line_items.find_by_product_id(product_id)
if current_item
current_item.quantity += 1
else
current_item = line_items.build(product_id: product_id)
end
current_item
end
def decrease(line_item_id)
current_item = line_items.find(line_item_id)
if current_item.quantity > 1
current_item.quantity -= 1
else
current_item.destroy
end
current_item
end
def increase(line_item_id)
current_item = line_items.find(line_item_id)
current_item.quantity += 1
current_item
end
def total_price
line_items.to_a.sum { |item| item.total_price }
end
end
・order.rb
class Order < ApplicationRecord
PAYMENT_TYPES = ["現金","クレジットカード","注文書"]
has_many :line_items, dependent: :destroy
validates :name, :address, :email, presence: true
validates :pay_type, inclusion: PAYMENT_TYPES
def add_line_items_from_cart(cart)
cart.line_items.each do |item|
item.cart_id = nil
line_items << item
end
end
end
・line_item.rb
class LineItem < ApplicationRecord
belongs_to :order
belongs_to :product
belongs_to :cart
def total_price
product.price * quantity
end
end
以上です。
色々試してみたところ、line_item.rbのbelongs_to :orderを消すとカート機能はうまくいきます。ですがオーダー機能がうまく行かなくなるので、やはりbelongs_to :orderは必要なのかなと思ってきてはいるのですがどうしたらいいものか。。。という現状です。
ちなみにカートに追加した時のターミナルの記述には rollback transaction が発生しております。
後、参考にしている本ではscaffoldを使っているのですが自分はscaffold使わないようにしていますのでそのら辺での不具合もあるのかもしれません。
以上です。気になるところなどアドバイスいただけると幸いです。よろしくお願いしますm(_ _)m