質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • Ruby

    6994questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

ecサイト、注文した履歴の出し方

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 108

takeke

score 11

ecサイト作っていまして、現在カート機能と、注文機能を作ったのですが、注文した後に何の商品が注文されて、誰が注文したのかがデータとして取れなくて困っています。

今の流れは、商品をカートに入れて、ログインしてる人はそこから注文画面へ。注文画面、フォームは新たに名前や住所、メアドなど入力し、不備がなければ注文確定になり、そこに書いたメアドに確認メール(注文内容の記載なし)で、カートは削除されます。その後注文の履歴をみると、注文のフォームに書いた情報と注文日時しか確認ができないといった具合です。

これを履歴確認画面で注文時の情報を、今の情報に加え、注文時のカートの中身と注文したユーザーの名前もみれるようにしたいのですが、どうしたらよいでしょうか?

とりあえず必要そうなコード下に載せておきます。

order.rb

class Order < ApplicationRecord
    PAYMENT_TYPES = ["現金","クレジットカード","注文書"]
    has_many :line_items, dependent: :destroy
    belongs_to :user
    validates :name, :address, :email, presence: true
    validates :pay_type, inclusion: PAYMENT_TYPES

    default_scope -> { order(created_at: :desc) }

    def add_line_items_from_cart(cart)
        cart.line_items.each do |item|
            item.cart_id = nil
            line_items << item
        end
    end
end


product.rb

class Product < ApplicationRecord

    has_many :line_items
    has_many :orders, through: :line_items
    has_many :users, through: :favorites
    validates :title, :description, presence: true
    validates :price, numericality: {greater_than_or_equal_to: 0.01}
    validates :title, uniqueness: true
    validates :image_url, allow_blank: true, format: {
        with:  %r{\.(gif|jpg|png)\z}i,
        message: 'はgif,jpg,png画像のURLでなければなりません' 
    } 
end


line_item.rb

class LineItem < ApplicationRecord
    # belongs_to :order
    belongs_to :product
    belongs_to :cart

    def total_price
        product.price * quantity
    end
end


user.rb

class User < ApplicationRecord
    validates :email,presence: true
    validates :name, presence: true, uniqueness: true
    has_secure_password
    after_destroy :ensure_an_admin_remains
     has_many :products
     has_many :orders
end


application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authorize

  helper_method :current_user, :logged_in?

  private

  def authorize
    unless User.find_by_id(session[:user_id])
      redirect_to login_url, notice: "ログインしてください"
    end
  end

  def authenticate
      return if logged_in?
      redirect_to login_url, alert: 'ログインしてください'
  end

  def current_cart
    if session[:cart_id]
      @cart = Cart.find(session[:cart_id])
    else
      @cart = Cart.create
      session[:cart_id] = @cart.id
      @cart
    end
  end

  def current_user
      return unless session[:user_id]
      @current_user ||= User.find session[:user_id]
  end

  def logged_in?
      !!session[:user_id]
  end
end


carts_controller.rb

class CartsController < ApplicationController
  # before_action :set_cart, only: [:show, :edit, :update, :destroy]
  skip_before_action :authorize, only: [:create, :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 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
end


line_item_cotroller.rb

class LineItemsController < ApplicationController
  skip_before_action :authorize, only: :create
  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

  private
    def set_line_item
      @line_item = LineItem.find(params[:id])
    end

    def line_item_params
      params.fetch(:line_item, {})
    end
end


orders_controller.rb

class OrdersController < ApplicationController
    skip_before_action :authorize, only: [:new, :create]
    before_action :authenticate


  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)
      @example = Order.new(@order)
      @example.add_line_items_from_cart(current_cart)

      respond_to do |format|
          if @example.save
              Cart.destroy(session[:cart_id])
              session[:cart_id] = nil
              OrderNotifierMailer.received(@example).deliver
              # binding.pry
              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"}
              @order = @example
              format.json {render json: @order.errors,
                  status: :unprocessable_entity}
          end
      end
  end

  def index
    # @orders = Order.paginate :page=>params[:page], :order=>'created_at desc',
    # :per_page => 10
    # @orders = Order.page(params[:page], :per_page => 10)
    @orders = Order.paginate(:page => params[:page], :per_page => 10)
    # Order = created_at: :desc

    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

schema.rb

ActiveRecord::Schema.define(version: 20180417103344) do

  create_table "carts", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "line_items", force: :cascade do |t|
    t.integer "product_id"
    t.integer "cart_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "quantity", default: 1
    t.integer "order_id"
  end

  create_table "orders", force: :cascade do |t|
    t.string "name"
    t.text "address"
    t.string "email"
    t.string "pay_type"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "products", force: :cascade do |t|
    t.string "title"
    t.text "description"
    t.string "image_url"
    t.decimal "price", precision: 8, scale: 2
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "category_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "name"
    t.string "password_digest"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "email"
    t.string "reset_digest"
    t.datetime "reset_sent_at"
  end

end

必要そうなコードはこのくらいでしょうか。足りたい部分ありましたら追記しますので言ってください。

とりあえずオーダーフォームに<%= hidden_field_tag %>でユーザーを特定させれるようにするのだろうなとは思い至るのですが、実際どう記述したらいいか。。。(もしかしてここにカートの情報も記述する??)

後、orders_controllerのcreateにカートの情報を保存する記述も必要??

ordersテーブルにカラム追加しなくちゃなのかな?とか。。。と、色々思うことはあるのですが実際何したらいいかわかりません。

最終的には、orderのshowで注文時の情報を全てみれるようにしたいので、もし今回の記事をご覧になっていただけた方で何かわかる方いましたらご教授の方よろしくお願いいたしますm(._.)m

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • te2ji

    2018/04/26 18:36

    何をやって、うまくいかないのでしょうか?丸投げしているようにしか思えないのですが。。。

    キャンセル

  • takeke

    2018/04/27 13:05

    ご覧いただきありがとうございます。質問記事では記述が多くなってしまい字数制限に引っかかってしまいとりあえずデータだけ載せるに至りました。やったことはordersにカラム追加してひとまずオーダーフォームにカートの情報とユーザーidを出そうと思ったのですが、その時点で詰んでしまっています。具体的には、ordersテーブルにuser_id,product_id,quantityを追加し、orders.rbにbelongs_to :user, users.rbにhas_many :orders, orders_controllerのcreateに@user = current_user フォーム内に<%= hidden_field_tag (:user), @user %>です。この時フォーム上でuserが存在しなくてはいけませんというエラーが出てきてます。ファイルを複製して作業しているので質問文では余計なことする前のコードを載せております。

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Ruby

    6994questions

    Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。