1

我真的一直在摸不着头脑,非常感谢帮助。我有一个商店设置,人们可以在那里上课。我有课程模型、订单模型和优惠券模型。以下是模型中的关联

class Course < ActiveRecord::Base
    belongs_to :category
    has_many :orders
    has_many :coupons
end

class Order < ActiveRecord::Base
    belongs_to :course
    belongs_to :user
        belongs_to :coupon
end
class Coupon < ActiveRecord::Base
    belongs_to :course
    has_many :orders
end

我有一个非常简单的优惠券模型设置,其中包含 code 和 newprice 列。我希望某人能够在新订单页面上填写优惠券表格并更新价格。

在我看来,对于新订单,我有两种形式,一种用于新订单,另一种用于优惠券。如果用户输入了正确的优惠券代码,如何签入我的控制器?如何更新要显示的优惠券价格而不是课程价格?

这是我的订单控制器

class OrdersController < ApplicationController
  before_action :set_order, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!


  def index
    @orders = Order.all
  end

  def show
  end

  def new
    course = Course.find(params[:course_id])
    @course = Course.find(params[:course_id])
    @order = course.orders.build
    @coupon = Coupon.new
    @user = current_user.id
    @useremail = current_user.email

  end

  def discount 
    course = Course.find(params[:course_id])
    @order = course.orders.build
    @user = current_user.id
    @useremail = current_user.email
  end

  def edit
  end

  def create
    @order = current_user.orders.build(order_params)
      if current_user.stripe_customer_id.present?
        if @order.pay_with_current_card
          redirect_to @order.course, notice: 'You have successfully purchased the course'
        else
          render action: 'new' 
        end
      else
        if @order.save_with_payment
          redirect_to @order.course, notice: 'You have successfully purchased the course'
        else
          render action: 'new' 
        end
      end
  end

  def update
      if @order.update(order_params)
        redirect_to @order, notice: 'Order was successfully updated.' 
      else
        render action: 'edit' 
      end
  end

  def destroy
    @order.destroy
    redirect_to orders_url
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_order
      @order = Order.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def order_params
      params.require(:order).permit(:course_id, :user_id, :stripe_card_token, :email)
    end
end
4

1 回答 1

6

您可以使用带有选项的form_for助手通过:remoteAJAX 请求来完成此操作。

概括

  1. 为您的表单设置:remote选项以提交 AJAX 请求。truecoupons
  2. 创建控制器操作以处理来自表单的 AJAX 请求。
  3. 使用 JavaScript 响应控制器操作以orders使用新的价格信息等更新您的表单(您视图中的另一个表单)。

使用 `:remote` 的 AJAX 请求

这是一些代表您的coupon表单的示例代码:

<%= form_for @coupon, method: :post,  url: check_coupon_code_path, remote: true do |f| %>
    <%= f.text_field :coupon_code, :placeholder => "Enter your coupon" %>
    <%= f.submit "Submit Coupon Code" %>
<% end %> 

请注意以下事项:

  • 标记的:remote选项设置为。form_fortrue
  • :url选项是您的控制器操作的路径CouponsController。因为该:remote选项设置为true,所以请求将:url作为 AJAX 请求发布到该选项。
  • 在这个代码示例中,假设它在routes.rb文件中定义了一个这样的路由来处理检查优惠券代码的 AJAX 请求:
    • post 'check_coupon_code' => 'coupons#check_coupon_code'
    • 注意:在forms_for帮助程序中,:url选项附加_pathroutes.rb文件中定义的前缀。
    • 额外说明:使用命令rake routes查看可用路由及其各自的控制器操作目标。

在 Controller 中处理 AJAX 请求

在您的CouponsController中,定义check_coupon_code处理上述 AJAX 请求的操作form_for

def check_coupon_code
  # logic to check for coupon code here

  respond_to do |format|
    if # coupon code is valid
      format.js   {}
    else
      # some error here
    end
  end
end

注意动作块中的format.jsrespond_to这允许控制器使用 JavaScript 响应 AJAX 请求,以更新orders视图中的表单。您必须定义一个相应的app/views/coupons/check_coupon_code.js.erb视图文件,该文件生成将在客户端发送和执行的实际 JavaScript 代码(或者check_coupon_code.js.coffee如果您使用的是 CoffeeScript,则命名 JavaScript 文件)。

使用 JavaScript 更新

然后,您文件中的 JavaScriptcheck_coupon_code.js.erb将更新您order表单中的价格。

警告:即使您使用 JavaScript 在客户端(即浏览器)更改订单价格,也必须在后端(即在您的控制器中)再次验证实际价格,以防某些恶意用户尝试操纵浏览器的请求等。

您可以查看官方 RailsGuide 以获取另一个示例

于 2014-04-24T20:30:13.207 回答