Рубин на рельсах и модель купона

Я действительно ломал голову над этим и был бы очень признателен за помощь. У меня есть магазин, где люди могут пройти курсы. У меня есть модель курса, модель заказа и модель купона. Вот ассоциации в моделях

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

У меня есть очень простая настройка модели купона, которая имеет код и столбцы новых цен. Я хочу, чтобы кто-то смог заполнить форму купона на новой странице заказа и обновить цену.

На мой взгляд, для нового заказа у меня есть две формы, одна для нового заказа и одна для купона. Как проверить мой контроллер, если пользователь ввел правильный код купона? Как обновить отображаемую цену купона вместо цены курса?

вот мой контролер заказов

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 ответ

Вы можете сделать это с помощью запроса AJAX, используя form_for помощник с :remote вариант.

Резюме

  1. Задавать :remote возможность true для тебя coupons Форма для отправки запроса AJAX.
  2. Создайте действие контроллера для обработки запроса AJAX из формы.
  3. Используйте JavaScript для ответа на действие контроллера для обновления вашего orders форма (другая форма на ваш взгляд) с новой ценовой информацией и т. д.

AJAX-запрос с использованием `:remote`

Вот пример кода, представляющего ваш 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_for тег установлен на true,
  • :url Опция путь к вашему действию контроллера в вашем CouponsController, Поскольку :remote опция установлена ​​в true, запрос будет опубликован на этом :url опция как запрос AJAX.
  • В этом примере кода предполагается, что у него есть маршрут, определенный следующим образом: routes.rb файл для обработки AJAX-запроса на проверку кода купона:
    • post 'check_coupon_code' => 'coupons#check_coupon_code'
    • Примечание: в forms_for помощник, :url опция добавляется _path на префикс, определенный в routes.rb файл.
    • Бонус примечание: используйте команду rake routes чтобы увидеть доступные маршруты и их соответствующие цели действий контроллера.

Обрабатывать 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.js в respond_to блок действий. Это позволяет контроллеру отвечать на запрос AJAX с помощью JavaScript для обновления вашего orders Форма на ваш взгляд. Вы должны будете определить соответствующий app/views/coupons/check_coupon_code.js.erb просмотреть файл, который генерирует реальный код JavaScript, который будет отправлен и выполнен на стороне клиента (или назовите файл JavaScript check_coupon_code.js.coffee если вы используете CoffeeScript).

Обновление с помощью JavaScript

JavaScript в вашем check_coupon_code.js.erb Затем файл обновит цену в вашем order форма.

ПРЕДУПРЕЖДЕНИЕ. Даже если вы используете JavaScript для изменения цены заказа на стороне клиента (то есть в браузере), очень важно снова проверить действительную цену в серверной части (т.е. в вашем контроллере) на случай, если какой-нибудь злонамеренный пользователь попытается манипулировать запросом браузера и т. д.

Вы можете увидеть официальный RailsGuide для другого примера.

Другие вопросы по тегам