訂單實(shí)作思路-上篇

前言

本文是[購(gòu)物車實(shí)作思路](/Users/xyy/Documents/知識(shí)專題/ruby on rails/全棧營(yíng)學(xué)習(xí)/學(xué)習(xí)總結(jié)/購(gòu)物車實(shí)作思路.md)的續(xù)篇,由于消費(fèi)者確定好購(gòu)物車中的商品和數(shù)量,接下來(lái)就是要下單,所以本文主要來(lái)描述訂單實(shí)作的思路。

1.建立訂單結(jié)賬頁(yè)

(1)設(shè)定訂單結(jié)賬頁(yè)面的路徑

resources :carts do
collection do
delete :clean
+ post :checkout
end
end

(2)修改購(gòu)物車carts/index頁(yè)面,為"確認(rèn)結(jié)賬"按鈕,添加路徑

- <%= link_to("確認(rèn)結(jié)賬","#",method: :post)  %>
+ <%= link_to("確認(rèn)結(jié)賬",checkout_carts_path,method: :post) %>

之所以要用collection,是因?yàn)槲覀円獙?duì)購(gòu)物車中所有的商品而不是某一件商品進(jìn)行操作
(3)建立訂單order的model
其中,我們要存儲(chǔ)購(gòu)物車內(nèi)所有商品的總結(jié)total
訂單的建立者user_id
寄件人信息billing_name,billing_address
和收件人信息shipping_name,shipping_address
終端執(zhí)行:
rails g model order
在新生成的migration文件中加入:

  t.integer :total, default: 0
      t.integer :user_id
      t.string :billing_name
      t.string :billing_address
      t.string :shipping_name
      t.string :shipping_address

然后終端執(zhí)行:
rails db:migrate

(4)建立訂單order和用戶user之間的關(guān)系
一個(gè)用戶可以有很多個(gè)訂單
在user.rb中加入:

has_many :orders

在order.rb中加入:

belongs_to :user

(5)在carts_controller中建立結(jié)賬頁(yè)的checkout action

def checkout 
@order = Order.new
end

(6)建立結(jié)賬頁(yè)面的carts/checkout.htm.erb
重要的代碼部分:

<table>
<tbody>
      <% current_cart.cart_items.each do |cart_item| %>
      <tr>
        <td>
          <%= link_to(cart_item.product.title,product_path(cart_item.product)) %>
        </td>
        <td>
          <%= cart_item.product.price %>
        </td>
        <td>
          <%= cart_item.quantity %>
        </td>
      </tr>
      <% end %>
    </tbody>
    </table>
<h2>訂單資訊</h2>
  <div class="order-form">
    <%= simple_form_for %>
    <legend>訂購(gòu)人</legend>
    <div class="form-group col-lg-6">
      <%= f.input :billing_name %>
    </div>
    <div class="form-group col-lg-6">
      <%= f.input :billing_address %>
    </div>

    <legend>收件人</legend>
    <div class="form-group col-lg-6">
      <%= f.input :shipping_name %>
    </div>
    <div class="form-group col-lg-6">
      <%= f.input :shipping_address %>
    </div>

    <div class="checkout">
      <%= f.submit "生成訂單",class: "btn btn-lg btn-danger pull-right",
      data: {disable_with: "Submitting"} %>
    </div>
    <% end %>
    </div>

(7)限制必須填寫寄件人和收件人信息
在order.rb中加入:

validates :billing_name, presence: true
  validates :billing_address,presence: true
  validates :shipping_name,presence: true
  validates :shipping_address,presence: true

(8)建立訂單order的routes
在routes.rb中加入:

resources :orders

(9)建立生成訂單的create action
前面的checkout action只是讓用戶填入一些參數(shù):
寄件人和收件人的名稱,地址
create action才是把資料存入到資料庫(kù)中
終端執(zhí)行:
rails g controller orders
在新生成的orders_controller.rb中加入代碼,其中要指定order的欄位內(nèi)容,即購(gòu)物車商品的總計(jì)total和訂單建立者user,由于checkout action中已經(jīng)指定了訂單的寄件人和收件人信息,因此就不用在create里面再次指定一遍了:

  before_action :authenticate_user!,only:[:create]

  def create
    @order = Order.new(order_params) #獲取結(jié)賬頁(yè)面?zhèn)魅氲男畔ⅲㄟ@里是從checkout頁(yè)面獲取,因?yàn)閏heckout頁(yè)面的之前被我們?cè)O(shè)置成了order.new即創(chuàng)建order對(duì)象)傳入的信息包含了收件人和寄件人的信息
    @order.user = current_user #指定訂單的創(chuàng)建者是當(dāng)前登陸用戶
    @order.total = current_cart.total_price#指定訂單上顯示的總計(jì)是購(gòu)物車的商品總價(jià)
    if @order.save
      redirect_to order_path(@order)
    else
      render 'carts/checkout'
    end

  end
  private

  def order_params
    params.require(:order).permit(:billing_name, :billing_address, :shipping_name, :shipping_address)

  end

注意:
new和build互為別名,在新建訂單時(shí)我們是這樣寫的:

@order = Order.new(order_params)
 @order.user = current_user

也可以寫成:

@order = current_user.orders.new(order_params)

同理,限制用戶只能看到自己的訂單,我們可以這樣寫

def show
  @order = Order.find(params[:id])
  if @order.user != current_user
    redirect_to root_path
  end
end

也可以寫成:

def show
@order = current_user.orders.find(params[:id])
end

在使用后一種寫法時(shí),如果輸入其他用戶的訂單地址,localhost3000是紅色報(bào)錯(cuò),heroku(production)是直接404,最好不讓用戶知道他做了什么而導(dǎo)致錯(cuò)誤,這樣比較安全。

2.建立購(gòu)買明細(xì)

購(gòu)買明細(xì)和訂單明細(xì)不同的地方在于,訂單明細(xì)是下單時(shí)用的,就如我們上面做的整個(gè)第1步的內(nèi)容。而購(gòu)買明細(xì)的作用是接下來(lái)發(fā)送給用戶通知信用的,最重要的是購(gòu)買明細(xì)記錄了當(dāng)時(shí)的購(gòu)買商品的信息,以便用戶追溯查看,這個(gè)購(gòu)買明細(xì),還不能直接用 在order中用product_id 的方式記錄信息,然后通過(guò)order.product來(lái)獲取商品信息,因?yàn)樯唐返膬r(jià)格會(huì)改變,商品也可能會(huì)下架,因此我們就要新建一個(gè)product_list這個(gè)model來(lái)存儲(chǔ)當(dāng)時(shí)的購(gòu)買信息然后我們?cè)谟唵卧斍轫?yè)面用product_list中保存的資料,就可以查看當(dāng)時(shí)購(gòu)買商品時(shí)候的信息了,這樣即便商品價(jià)格變動(dòng),商品下架都不會(huì)對(duì)訂單詳情中的信息產(chǎn)生影響。

(1)新建購(gòu)買明細(xì)的model product_list
終端執(zhí)行:
rails g model product_list
在新生成的migration文件中加入:

      t.integer :order_id
      t.string :product_name
      t.integer :product_price
      t.integer :quantity

分別用來(lái)記錄購(gòu)買明細(xì)對(duì)應(yīng)的訂單,商品名稱,商品價(jià)格和商品購(gòu)買數(shù)量
終端執(zhí)行:
rake db:migrate

(2)建立訂單order和購(gòu)買明細(xì)product_list之間的關(guān)系
一個(gè)訂單可以有很多個(gè)購(gòu)買明細(xì)(因?yàn)槲覀冊(cè)谫?gòu)物車中可以放入很多中商品一起買,一種商品實(shí)際上就對(duì)應(yīng)了一個(gè)購(gòu)買明細(xì))
在order.rb中加入:

has_many :product_lists

在product_list.rb中加入:

belongs_to :order

(3)在訂單建立的時(shí)候同時(shí)建立購(gòu)買明細(xì)
這就需要在order的create action中加入代碼:

def create
if @order.save
+ current_cart.cart_items.each do |cart_item|
      +  product_list = ProductList.new
       +  product_list.order = @order
        + product_list.product_price = cart_item.product.price
        + product_list.product_name = cart_item.product.title
        + product_list.quantity = cart_item.quantity
        + product_list.save
+ end
redirect_to order_path(@order)
else
render 'carts/checkout'
end
end

(4)建立訂單詳情頁(yè)的action
在orders_controller中加入show action

def show
@order = Order.find(params[:id])
@product_lists = @order.product_lists
end

這里我們要找到對(duì)應(yīng)的訂單,并且需要用到訂單對(duì)應(yīng)的購(gòu)買明細(xì)product_list,等下會(huì)把它們?cè)谟唵卧斍轫?yè)面中進(jìn)行渲染

(5)建立訂單詳情頁(yè)orders/show.html.erb
在其中加入代碼:

<div class="row">
  <div class="col-md-12">
    <h2>訂單明細(xì)</h2>
    <table class="table table-bordered">
      <thead>
        <tr>
          <th width= "80%">商品明細(xì)</th>
          <th>單價(jià)</th>
        </tr>
      </thead>
      <tbody>
        <% @product_lists.each do |product_list| %>
        <tr>
          <td>
            <%= product_list.product_name %>
          </td>
          <td>
            <%= product_list.product_price %>
          </td>
        </tr>
        <% end %>
      </tbody>
    </table>

    <div class="total clearfix">
      <span class="pull-right">
        總計(jì) <%= @order.total %> CNY
      </span>
    </div>

    <hr>
    <h2>寄送資訊</h2>
    <table class="table table-striped table-bordered">
      <tbody>
        <tr>
          <td>訂購(gòu)人</td>
        </tr>
        <tr>
          <td>
            <%= @order.billing_name %> - <%= @order.billing_address %>
          </td>
        </tr>
        <tr>
          <td>收件人</td>
        </tr>
        <tr>
          <td>
            <%= @order.shipping_name %> - <%= @order.shipping_address %>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

3.將網(wǎng)址改為亂碼序號(hào)

之前我們訂單在打開(kāi)時(shí),顯示的網(wǎng)址是其id,這樣隱私性比較差,別人很容易知道你的訂單成交量,或者找到規(guī)律。因此,我們要將訂單的網(wǎng)址改成亂碼序號(hào),提高隱私性。
(1)在order上新建欄位token,用來(lái)保存亂碼序號(hào)
終端執(zhí)行:
rails g migration add_token_to_order
在新生成的migration文件中加入:

  + add_column :orders, :token,:string

終端執(zhí)行:
rails db:migrate

(2)在order.rb中新建產(chǎn)生亂碼序號(hào)的generate_token方法,并將該方法掛在before_create上

  before_create :generate_token

  def generate_token
    self.token = SecureRandom.uuid
  end

注意:
before_create 是 Rails model 內(nèi)建的 callbacks,目的是讓資料生成儲(chǔ)存前先執(zhí)行某某動(dòng)作。model其實(shí)就是一個(gè)ActiveRecord類,每筆資料(或者說(shuō)物件,對(duì)象)都是model的實(shí)例,model是用來(lái)操作資料庫(kù)的,因此在將亂碼數(shù)字存入到資料庫(kù)中,就需要在存入前進(jìn)行操作,所以要將before_create寫在model中,然后會(huì)繼續(xù)去執(zhí)行controller中的create方法,最終將資料存入資料庫(kù)

(3)進(jìn)入orders_controller的create action和show action中修改代碼,完成重導(dǎo)網(wǎng)址
由于我們把亂碼序號(hào)作為網(wǎng)址,因此需要顯性指定order_path中傳入的參數(shù)是order.token,否則路徑仍然會(huì)默認(rèn)調(diào)取order的id,因此要對(duì)按鈕或者重導(dǎo)路徑做如下修改:

def create
....
- redirect_to order_path(@order)
+ redirect_to order_path(@order.token)
...
end

同時(shí)也要把獲得訂單的方式改成用token方式獲得,因此要對(duì)show action做如下修改:

def show
- @order = Order.find(params[:id])
+ @order = Order.find_by_token(params[:id])
end

4.用戶可以看到自己的所有訂單

(1)新建路由

namespace :account do
resources :orders
end

用account/orders是為了和之前的order做區(qū)別,你也將可以將order定義成其他名稱

(2)修改導(dǎo)航欄加入"我的訂單"選項(xiàng)

<li><%= link_to("我的訂單",account_orders_path) %></li>

(3)新建account/orders_controller.rb,在其中建立index action
終端執(zhí)行:
rails g controller account::orders
然后在心生成的account/orders_controller.rb中加入:

before_action :authenticate_user!
def index
@order = current_user.orders.order"id DESC"
end

其中DESC是按照從新到舊的順序排列訂單

(4)新建"我的訂單"頁(yè)面app/views/account/orders/index.html.erb
在其中加入代碼:

<h2>訂單列表</h2>
<table class="table table-bordered">
  <thead>
    <tr>
      <th>#</th>
      <th>生成時(shí)間</th>
    </tr>
  </thead>
  <tbody>
    <% @orders.each do |order| %>
    <tr>
      <td>
        <%= link_to(order.id,order_path(order.token)) %>
      </td>
      <td>
        <%= order.created_at.to_s(:long) %>
      </td>
    </tr>
    <% end %>
  </tbody>
</table>

其中to_s(:long)可以把created_at和updated_at的時(shí)間格式進(jìn)行修改,具體可參考:[修改時(shí)間格式的方法](/Users/xyy/Documents/知識(shí)專題/ruby on rails/12 WebApps in 12 Weeks/修改時(shí)間格式的方法.md)

(5)這時(shí)候進(jìn)入"我的訂單"頁(yè)面會(huì)出現(xiàn)報(bào)錯(cuò),我們需要解決報(bào)錯(cuò)


006tKfTcly1fnrw33nybuj31d60hmdjw.jpg

報(bào)錯(cuò)信息提示orders_controller中的show action缺少[:id],不能正常重導(dǎo)至show網(wǎng)頁(yè)
在看看orders_controller中的show action的代碼:

  def show
    @order = Order.find_by_token(params[:id])
    @product_lists = @order.product_lists
  end

說(shuō)明無(wú)法通過(guò)params[:id]找到對(duì)應(yīng)的訂單
這是由于,訂單的亂碼序號(hào)token是我們后面加入的,之前的訂單都沒(méi)有token,因此那些沒(méi)有亂碼序號(hào)的訂單就無(wú)法通過(guò)token傳入?yún)?shù)到params[:id],也就無(wú)法找到對(duì)應(yīng)的訂單了。
解決辦法:
進(jìn)入rails console,輸入指令Order.where(token: nil).destroy_all將沒(méi)有token的訂單全部刪除掉,再進(jìn)入"我的訂單"就正常了

補(bǔ)充:

1.關(guān)于關(guān)系的建立:has_many和belongs_to
根據(jù)需要我們有時(shí)候需要同時(shí)設(shè)定has_many和belongs_to,從而建立完整的成對(duì)映射關(guān)系;但有時(shí)候如果只需要其中一個(gè),也可以建立不成對(duì)的映射關(guān)系。
例如本例子中建立的order和user之間的映射關(guān)系
user.rb中:

has_many :orders

order.rb中:

belongs_to :user

由于我們?cè)趏rders_controller的create action中用到了:

@order.user = current_user

并且用戶可以看到自己的orders,在account/orders_controller中

def index
@orders = current_user.orders
end

其實(shí)都是為了記錄或者找到訂單order對(duì)應(yīng)的用戶user。
總而言之:如果order需要調(diào)用user,那么order.rb中一定要有belongs_to :user
如果user要調(diào)用order,那么user.rb中一定要有has_many: orders
比如,如果order想要調(diào)用user,但卻沒(méi)有belongs_to :user,則會(huì)出現(xiàn)下面的問(wèn)題:

從圖中可以看出,在沒(méi)有order.rb中沒(méi)有belongs_to :user的情況下,是不能調(diào)用user的,雖然能找到user_id是誰(shuí),但這個(gè)user_id其實(shí)是order自身的欄位內(nèi)容,其實(shí)還是沒(méi)有調(diào)取到user。

在[訂單實(shí)作思路](/Users/xyy/Documents/知識(shí)專題/ruby on rails/全棧營(yíng)學(xué)習(xí)/學(xué)習(xí)總結(jié)/訂單實(shí)作思路.md)中我們也提到過(guò),在建立了cart和cart_item,以及product之間的聯(lián)系時(shí),我們?cè)赾art.rb中這樣寫:

has_many :cart_items
  has_many :products, through: :cart_items, source: :product

在cart_item.rb中這樣寫:

  belongs_to :cart
  belongs_to :product
end

但卻沒(méi)有在product中設(shè)置

has_many :cart_items
has_many :carts, through: :cart_items, source: :cart

這是因?yàn)槲覀冎恍枰ㄟ^(guò)cart_item來(lái)調(diào)用product,從而知道每個(gè)購(gòu)物欄放了什么商品,但卻不需要通過(guò)product來(lái)獲取它對(duì)應(yīng)的購(gòu)物欄cart_item是什么,
同樣的,我們想通過(guò)購(gòu)物車cart來(lái)調(diào)取products來(lái)獲取購(gòu)物車中放了什么種類的商品product,但卻不用product來(lái)尋找對(duì)應(yīng)的購(gòu)物車cart,而是把分配和尋找購(gòu)物車的任務(wù)交給了session,因此我們并沒(méi)有在product中建立has_many :cart_itemshas_many :carts, through: :cart_items, source: :cart

2.關(guān)于路徑中的id

006tKfTcgy1fnrlmmplu7j313q07igng.jpg

(1)默認(rèn)情況下路徑參數(shù)調(diào)用的是id
(2)圖中的id指的是參數(shù)params[:id]
本例中要將亂碼序號(hào)作為網(wǎng)址,需要將亂碼序號(hào)token欄位中的內(nèi)容作為參數(shù),傳入到params[:id]中,從而才能作為網(wǎng)址

@order = Order.find_by_token(params[:id])

并且需要在按鈕的路徑上或者跳轉(zhuǎn)到的頁(yè)面上調(diào)用token作為路徑參數(shù)。
因此創(chuàng)建后訂單后,要跳轉(zhuǎn)到訂單詳情頁(yè)面,因此我們?cè)趏rder的create action中指定的路徑是:

redirect_to order_path(@order.token)

其中:

@order = Order.find_by_token(params[:id])

等價(jià)寫法是:

@order = Order.find_by(token: params[:id])

這樣就可以token作為參數(shù)id傳入到路徑中。
因此當(dāng)使用亂數(shù)序號(hào)時(shí),需要顯性指定傳入的參數(shù),例如本例子中的token。
同理,在[訂單實(shí)作思路](/Users/xyy/Documents/知識(shí)專題/ruby on rails/全棧營(yíng)學(xué)習(xí)/學(xué)習(xí)總結(jié)/訂單實(shí)作思路.md)中,我們寫過(guò):

@cart_item = current_cart.cart_items.find_by(product_id: params[:id])

在購(gòu)物車詳情頁(yè)的刪除某一商品的路徑寫成:

<%= link_to cart_item_path(cart_item.product_id), method: :delete do %>
 <i class="fa fa-trash"></I>
 <% end %>

也是由于我們是通過(guò)product_id尋找cart_item,因此路徑參數(shù)要傳入的是product_id
而如果使用cart_item自身的id來(lái)尋找cart_item,即:

@cart_item = current_cart.cart_items.find(id: params[:id])

那么在購(gòu)物車詳情頁(yè)的刪除某一商品的路徑要對(duì)應(yīng)寫成:

<%= link_to cart_item_path(cart_item.id), method: :delete do %>
 <i class="fa fa-trash"></I>
 <% end %>

其中路徑中的cart_item.id也可以換成用cart_item,這是因?yàn)槁窂絽?shù)默認(rèn)傳入的就是id,即便我們寫的cart_item,它也會(huì)撈出其中的cart_item.id傳給路徑
總結(jié):如果不是model對(duì)象自身的id撈出對(duì)象,那么都需要顯性指定撈取的方式是什么,并且將這種撈取方式對(duì)應(yīng)的參數(shù)傳入到路徑中

3.關(guān)于結(jié)賬頁(yè)checkout action的請(qǐng)求動(dòng)作
new action在routes中默認(rèn)是的請(qǐng)求動(dòng)作是GET,checkout action雖然和new action名稱不一樣,但是方法中的代碼都是用new方法來(lái)新建對(duì)象,為什么這里checkout的請(qǐng)求動(dòng)作用的POST,是因?yàn)樾枰l(fā)送新表單的原因,還是因?yàn)榭梢杂肎ET動(dòng)作,只是考慮到駭客原因,改用POST動(dòng)作了呢?
答:
經(jīng)過(guò)測(cè)試驗(yàn)證,checkout action是可以用GET動(dòng)作的,使用POST動(dòng)作的原因應(yīng)該就是為了防駭客,這一點(diǎn)還需要后面繼續(xù)驗(yàn)證。

4.關(guān)于新建結(jié)賬頁(yè)的checkout action是否一定要用在carts_controller中,或者是否一定要用checkout action,可以用new action嗎?
答:
我認(rèn)為這里checkout的路徑不一定要建立在resources :carts中,也可以新建別的controller,將checkout 放入對(duì)應(yīng)的resources中也是可行的。甚至是將checkout 改成new,使用orders_controller來(lái)完成訂單詳情頁(yè)也是可行的。不過(guò)這些都是我的猜測(cè),接下來(lái)通過(guò)實(shí)作驗(yàn)證下。
答:經(jīng)過(guò)驗(yàn)證得出新建訂單的checkout action可以不用放在resources :carts,也可以新建其他controller,放在其對(duì)應(yīng)的resources中,或者放在resources :orders中也是可以的,當(dāng)然可以直接用new action而不用checkout action也是可行的,action名稱其實(shí)是可以新建或修改的。但是需要注意的是如果不是resources默認(rèn)的7個(gè)action,那么需要在routes中resources設(shè)定默認(rèn)7個(gè)action外的其他action的路由。比如這里如果將checkout action放在resources :orders中需要指定collection do,并且要指定action 為checkout,并且請(qǐng)求方式為get 或者post;而如果使用的是new action則不用顯性指定 new action和請(qǐng)求動(dòng)作。

結(jié)論:
從上述carts_controller.rb中的checkout action

def checkout 
@order = Order.new
end

可以看出,用model建立的新對(duì)象(物件)不用和controller名稱對(duì)應(yīng),只要有需要任何model建立的對(duì)象都可以用在其他controller中,比如這里在carts_controller中可以建立訂單Order的新對(duì)象。
5.為什么用product_list建立購(gòu)買明細(xì)就可以不隨著商品信息變化而發(fā)生變化呢?
答:這是因?yàn)閜roduct_list的資料寫入過(guò)程用的是賦值運(yùn)算符"=",當(dāng)用賦值運(yùn)算符進(jìn)行賦值運(yùn)算時(shí),integer,float等Fixnum類型,和string類型,symbol類型,range類型的以及hash類型值有如下特點(diǎn):

006tNc79ly1fnsmvnkvd8j30yk0hqgmw.jpg

即如果變量a通過(guò)賦值運(yùn)算給其他變量b進(jìn)行賦值后,再次改變變量a,變量b的值不受影響
而數(shù)組類型則不同,它是指向同一個(gè)地址,當(dāng)?shù)刂穼?duì)應(yīng)的數(shù)值發(fā)生變化,所有指向該地址的值都將改變,如圖:


006tNc79ly1fnsn0dk20wj30jc09ewf4.jpg

可以看出數(shù)組arr將值賦值給數(shù)組br后,再次改變數(shù)組arr的值,那么數(shù)組br的值也會(huì)發(fā)生同樣的改變
因此,在使用product_list時(shí)我們用的也是賦值運(yùn)算,對(duì)其中的product_name用的是string,quantity和product_price,order_id用的都是integer。這樣通過(guò)賦值運(yùn)算后,即便原來(lái)的商品名稱,價(jià)格都發(fā)生了變化,也不會(huì)影響到product_list中的數(shù)值。
而如果直接在order中通過(guò).調(diào)用product的話,如果商品的信息發(fā)生變化,商品明細(xì)也會(huì)發(fā)生變化,這樣我們就無(wú)法記錄當(dāng)初買下商品那一刻的商品價(jià)格,名稱等信息。
值得注意的是新建欄位或新建migration時(shí)sqlite3不支持?jǐn)?shù)組類型,需要使用Json來(lái)轉(zhuǎn)載,例如:

add_column :products, :photos, :string

此時(shí)的photo是并不是數(shù)組類型,仍然是string類型,要想把photos作為數(shù)組類型,需要到product model中加上:

serialize :photos, JSON

那么這個(gè)photos就同JSON轉(zhuǎn)載成數(shù)組類型

6.為什么只需要在create action中記錄用戶,總價(jià),購(gòu)買明細(xì)等信息,其他action 就不用再顯性指明了呢?
答:通過(guò)例子來(lái)解釋,首先看order的create action,代碼如下:

def create
    @order = Order.new(order_params)
    @order.user = current_user
    @order.total = current_cart.total_price

    if @order.save
      current_cart.cart_items.each do |cart_item|
        product_list = ProductList.new
        product_list.order = @order
        product_list.product_price = cart_item.product.price
        product_list.product_name = cart_item.product.title
        product_list.quantity = cart_item.quantity
        product_list.save
      end
      redirect_to order_path(@order.token)
    else
      render 'carts/checkout'
    end

  end

其中在create action中用了new(order_params),將新建訂單頁(yè)面?zhèn)魅氲募募撕褪占诵畔魅?,又指定了訂單建立者,?gòu)物車中的商品總價(jià),并且記錄了訂單中的購(gòu)買信息product_lists,最后一并寫入到資料庫(kù)中。這樣其實(shí)就將order的欄位內(nèi)容和其相關(guān)的model(這里是product_list)內(nèi)容一一填寫上了。
由于在create action中已經(jīng)將order和其相關(guān)的product_list欄位內(nèi)容已經(jīng)填入到資料庫(kù),其他action其實(shí)都是對(duì)資料庫(kù)進(jìn)行操作,因此不用重新在指定欄位對(duì)應(yīng)的內(nèi)容,需要調(diào)用什么內(nèi)容直接從資料庫(kù)中取出即可。
例如order的show action:

def show
    @order = Order.find_by_token(params[:id])
    @product_lists = @order.product_lists
  end

就是從資料庫(kù)中找到對(duì)應(yīng)的訂單@order,并且撈出該訂單相關(guān)的購(gòu)買明細(xì)@product_lists,然后在html中調(diào)用繪制出頁(yè)面即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容