Ruby on rails and coupon model

大憨熊 提交于 2019-12-01 11:14:59

问题


I have really been scratching my head on this and would greatly appreciate help. I have a store setup where people can take courses. I have a course model, order model, and coupon model. Here are the associations in the models

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

I have a very simple coupon model setup that has code and newprice columns. I want the ability for someone to be able to fill out the coupon form on the new order page and it to update the price.

In my my view for new order I have two forms one for the new order and one for the coupon. How do check in my controller if a user has entered the correct coupon code? How do I update the coupon price to be shown instead of the course price?

here is my order controller

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

回答1:


You can accomplish this with an AJAX request using the form_for helper with the :remote option.

Summary

  1. Set :remote option to true for your coupons form to submit the AJAX request.
  2. Create controller action to handle the AJAX request from the form.
  3. Use JavaScript to respond to the controller action to update your orders form (the other form in your view) with the new price information, etc.

AJAX request using `:remote`

Here's some example code representing your coupon form :

<%= 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 %> 

Notice the following:

  • The :remote option for the form_for tag is set to true.
  • The :url option is the path to your controller action in your CouponsController. Because the :remote option is set to true, the request will be posted to this :url option as an AJAX request.
  • In this code example, it's assuming it has a route defined like this in the routes.rb file to handle the AJAX request for checking the coupon code:
    • post 'check_coupon_code' => 'coupons#check_coupon_code'
    • Note: In the forms_for helper, the :url option appends _path to the prefix defined in the routes.rb file.
    • Bonus note: Use the command rake routes to see the available routes and their respective controller action targets.

Handle AJAX request in the Controller

In your CouponsController, define the action check_coupon_code to handle your AJAX request from the above 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

Notice the format.js in the respond_to block of the action. This allows the controller to respond to the AJAX request with JavaScript to update your orders form in your view. You'll have to define a corresponding app/views/coupons/check_coupon_code.js.erb view file that generates the actual JavaScript code that will be sent and executed on the client side (or name the JavaScript file check_coupon_code.js.coffee if you're using CoffeeScript).

Updating with JavaScript

The JavaScript in your check_coupon_code.js.erb file will then update the price in your order form.

WARNING: Even if you use JavaScript to change the order price on the client-side (i.e. the browser), it is critical to validate the actual price again in the back-end (i.e. in your controller) in case some malicious user tries to manipulate the browser's request, etc.

You can see the official RailsGuide for another example.



来源:https://stackoverflow.com/questions/23277917/ruby-on-rails-and-coupon-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!