首页 > 代码库 > [AWDwR4]13章 Playtime1 的实现

[AWDwR4]13章 Playtime1 的实现

13.PlayTime 1:
  向orders表加入ship_date字段,当OrdersController更新这个值后发送一个emial通知。这个官方网站上没有提供参考的答案,论坛里有简单版本我自己实现了一个稍微复杂一点的。
   我的思路是在每个order的show模板中加入一个按钮 Ship it now,每个order只有一次ship的机会,这样就避免了重复ship。
   step1:
   先在 orders_controller 中手动加入ship这个action:

# PUT /orders/1
  # PUT /orders/1.json
  def ship
    @order = Order.find(params[:id])

    respond_to do |format|
      if @order.ship_date.nil? && @order.update_attributes(:ship_date=>Time.now)
        Notifier.order_shipped(@order).deliver

        format.html { redirect_to @order, notice: ‘Order was successfully shiped.‘ }
        format.json { head :no_content }
      else
        format.html { redirect_to order_url(@order), notice: ‘Order already shiped.‘}
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

  使用了PUT方法,因为之前看过酷壳上的一篇文章讲到,PUT方法具有幂等性,所以对同一个order进行多次ship操作和一次ship操作的副作用是相同的。
  step2    因为ship这个action是手动添加进去的,所以需要手动添加路由,让Rails路由能够识别URL并将请求分发到order控制器的ship中,可参照成员(Member)路由:
     修改 config/routes.rb,加入:   

    resources :orders do
        put :ship, :on => :member
    end

  step3 在app/views/orders/show.html.erb模板中添加ship按钮

<% if @order.ship_date.nil? %>
    <%= button_to ‘Ship it now!‘, ship_order_path(@order), :method => :put %>
<% end%>

  其中使用了 ship_order_path这个helper,我是仿照 <%= link_to ‘Edit‘, edit_order_path(@order) %> 这个来写的,当时没有添加路由,所以报错,找不到这个函数。后来看了rails路由后,才明白 "建立一个 Resourceful 的路由的同时也会为你的应用自动添加一系列的 Helper 方法"这句话的意思。

[AWDwR4]13章 Playtime1 的实现