Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
验证优惠券代码并更新价格的控制器方法/Javascript_Javascript_Ruby On Rails_Ruby_Ruby On Rails 4 - Fatal编程技术网

验证优惠券代码并更新价格的控制器方法/Javascript

验证优惠券代码并更新价格的控制器方法/Javascript,javascript,ruby-on-rails,ruby,ruby-on-rails-4,Javascript,Ruby On Rails,Ruby,Ruby On Rails 4,我有一个结账页面,访客可以在其中输入优惠券,从而获得折扣。此外,我还有一个actioncode模型,其中包含所有可能的有效actioncodes,这些actioncodes是由管理员生成的。一个人可以提交一张优惠券,然后按下一个按钮,它应该验证优惠券,如果有效,自动更新价格。我试着按照答案中的步骤来做,但不完全确定如何做到这一点 当然,这应该以安全的方式进行。我最初的计划是通过Javascript实现的,但这里的答案让我确信这应该在控制器中完成(并且可能使用Javascript来更新签出视图上显

我有一个结账页面,访客可以在其中输入优惠券,从而获得折扣。此外,我还有一个actioncode模型,其中包含所有可能的有效actioncodes,这些actioncodes是由管理员生成的。一个人可以提交一张优惠券,然后按下一个按钮,它应该验证优惠券,如果有效,自动更新价格。我试着按照答案中的步骤来做,但不完全确定如何做到这一点

当然,这应该以安全的方式进行。我最初的计划是通过Javascript实现的,但这里的答案让我确信这应该在控制器中完成(并且可能使用Javascript来更新签出视图上显示的金额?)

我应该如何调整下面的代码以包含优惠券,以及应该包含哪些Javascript?就目前而言,当我按下优惠券按钮时,什么也没有发生


路由,提交新用户时执行
def checkout

post 'signup/register' => 'organizations#checkout', as: 'signup_checkout'
保存新用户并生成签出(付款)视图的控制器方法。它设置用于签出的各种变量:

  def checkout
    @organization = Organization.new(organizationnew_params)
    if @organization.save
      @organization.members.each do |single_member|
        single_member.send_activation_email
      end
      @actioncode = Actioncode.new
      @amount = 100.00
      @currency = "EUR"
      @description = @organization.id
      @transaction_description = "My description"
      @transaction_type = "S"
      @hash = hash(@description, @amount, @currency, @transaction_type)
      render 'checkout'   # This renders the checkout view.
    else                            
      render 'new_premium'
    end
  end
表单查看生成actioncode/优惠券表单的前四行:

<%= form_for @actioncode, method: :post, url: {action: "check_actioncode", :controller => 'actioncodes'}, remote: true do |f| %>
  <%= f.text_field :actioncode, :placeholder => "Enter your coupon" %>
  <%= f.submit "Submit Coupon Code" %>
<% end %>

<form action="https://secure.paylane.com/order/cart.html" method="post" >
  <%= "If you have a coupon, please enter that first. The amount due is #{@currency} #{number_with_precision(@amount, precision: 2)}. The button below will bring you to the secure environment of PayLane where you can select your payment method." %>
  <!-- form adapted from http://devzone.paylane.com/secure-form-guide/implementation/ -->
  <input type="hidden" name="amount" value=@amount />
  <input type="hidden" name="currency" value=@currency />
  <input type="hidden" name="merchant_id" value=PAYLANE_ID />
  <input type="hidden" name="description" value=@description />
  <input type="hidden" name="transaction_description" value=@transaction_description />
  <input type="hidden" name="transaction_type" value=@transaction_type />
  <input type="hidden" name="back_url" value="https://mysite/signup/confirmation" />
  <input type="hidden" name="language" value="en" />
  <input type="hidden" name="hash" value=@hash />
  <input type="hidden" name="customer_email" value=@member.email />
  <button type="submit">Pay with PayLane</button>
</form>
按下actioncode/优惠券按钮时执行的控制器方法

def check_actioncode
  @actioncode = Actioncode.where(:actioncode => params[:actioncode][:actioncode]).first
  respond_to do |format|
    unless @actioncode.empty?
      unless @actioncode.price.empty?
        @amount = @actioncode.price     # It it safe this way, or should (part of) the method be private?
        format.js {}             # What should the js file look like to update the values in the checkout view?
        render 'checkout'        # To reload page with the updated price/amount?
      else
        unless @actioncode.discount.empty?
          @amount = @amount * (100 - @actioncode.discount)  # Not sure how to do this. The first @amount should be yhr new amount, while the second @amount should be the initial amount.
          format.js {}
          render 'checkout'
        else
          flash.now[:danger] = "Action code offers no discount"
        end
      end
    else
      flash.now[:danger] = "Action code not found or expired"
    end
  end
end

删除了最初的Javascript代码,因为答案表明这不是一种安全的方法,例如更新数量。

您永远不应该只验证关键用户输入客户端(换句话说:使用Javascript)。这将是一个安全漏洞和可能的代码注入攻击的目标。
为什么不直接通过
post
将表单输入发送到控制器,并在那里用ruby进行验证呢?我认为这将更符合MVC(视图不应与模型对话)。

需要注意的是,您永远不会将操作代码带到UI。人们肯定会破解它

function validate(actioncode) {

    //Here make a call to your backend to validate. I RECOMMEND NOT TO DO IT IN UI.
    //Return somevalue
    //if you have the data in UI, you can use if(validActionCodes.indexOf(actioncode))
    if (isActionValid)
        window.alert("Action Code Accepted! Click the Buy Now button to finalize the payment");
    } else {
        window.alert("Sorry, The Action Code you entered is invalid. Please check and try again!");
    }
}

但是,代码不会被验证,价格也不会自动更新。还是会?我想我会同时做控制器和Javascript。控制器的安全原因和Javascript,以便验证和价格更新立即自动发生在结帐页面上。我认为这也是在会议上提出的。或者这也可以通过控制器实现,因为优惠券代码表单现在也包括一个按钮?根据我在这个问题上的理解,他们在Ruby中进行验证,并将布尔值发送到JavaScript继续。。不是动作代码本身,你能帮我实现吗?我不知道该如何更改我的代码。我已经更新了
def check\u actioncode
,以便(同时)在控制器中执行验证和金额更新。只需为代码提供一个自己的提交按钮,将其发布到控制器。然后用更新后的价格重新加载页面。如果您不想重新加载整个页面,我建议您阅读一些关于AJAX的内容,它使您能够在不重新加载和只更新页面的部分内容的情况下执行请求:)AFAIK已经有一些rails附带的帮助程序/模块,使使用AJAX编程变得舒适。但这不是我在代码中已经在做的事情吗?我有一个单独的优惠券表单,并尝试按照上面的步骤操作,这确实使用了AJAX。我的代码还不正确吗?你带到UI的任何东西最终用户都可以访问。。所以总是在后端验证
function validate(actioncode) {

    //Here make a call to your backend to validate. I RECOMMEND NOT TO DO IT IN UI.
    //Return somevalue
    //if you have the data in UI, you can use if(validActionCodes.indexOf(actioncode))
    if (isActionValid)
        window.alert("Action Code Accepted! Click the Buy Now button to finalize the payment");
    } else {
        window.alert("Sorry, The Action Code you entered is invalid. Please check and try again!");
    }
}