【问题标题】:Stripe Payment: undefined method `price' for nil:NilClass条纹支付:nil:NilClass 的未定义方法“价格”
【发布时间】:2016-10-23 20:57:31
【问题描述】:

我有一个正在测试条带支付的应用程序。现在,我正在尝试配置收费,以便它从另一个模型(pin.price)获取价格并正确收费。到目前为止,我遇到了以下错误消息:

ChargesController#create 中的 NoMethodError nil:NilClass 的未定义方法“价格”

app/controllers/charges_controller.rb

class ChargesController < ApplicationController

    def create
      # Amount in cents
      @amount = (@pin.price * 100).floor

      customer = Stripe::Customer.create(
        :email => params[:stripeEmail],
        :card  => params[:stripeToken]
      )

      charge = Stripe::Charge.create(
        :customer    => customer.id,
        :amount      => @amount,
        :description => 'Rails Stripe customer',
        :currency    => 'usd'
      )

    rescue Stripe::CardError => e
      flash[:error] = e.message
      redirect_to charges_path
    end
end

app/controllers/pins_controller.rb

class PinsController < ApplicationController
  before_action :set_pin, only: [:show, :edit, :update, :destroy, :bid]
  before_action :correct_user, only: [:edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]

  .....

    def pin_params
      params.require(:pin).permit(:description, :price, :image, :manufacturer, :model)
    end
end

应用程序/数据库/迁移

class AddPriceToPins < ActiveRecord::Migration
  def change
    add_column :pins, :price, :decimal
  end
end

我很确定错误来自“@amount = (@pin.price * 100).floor”,但我只是不确定如何更好地表达这个数量,所以每个 pin 的价格不是静态的,而是匹配的到它在数据库中的当前输入值。

编辑:在此处包括带有条形支付代码链接的表单:

 <%= form_tag charges_path, id: 'chargesForm' do %>
              <script src="https://checkout.stripe.com/checkout.js"></script>
              <%= hidden_field_tag 'stripeToken' %>
              <%= hidden_field_tag 'stripeEmail' %>  
              <button id="btn-buy" type="button" class="btn btn-success btn-lg btn-block"><span class="glyphicon glyphicon-heart"></span>   I want this!</button>

              <script>
                  var handler = StripeCheckout.configure({
                    key: '<%= Rails.configuration.stripe[:publishable_key] %>',
                    token: function(token, arg) {
                      document.getElementById("stripeToken").value = token.id;
                      document.getElementById("stripeEmail").value = token.email;
                      document.getElementById("chargesForm").submit();
                    }
                  });
                   document.getElementById('btn-buy').addEventListener('click', function(e) {
                    handler.open({
                      name: '<%= @pin.manufacturer %>',
                      description: '<%= @pin.description %>',
                      amount: '<%= (@pin.price * 100).floor %>'
                  });
                  e.preventDefault();
                 })
              </script>
          <% end %>

有什么想法吗?

【问题讨论】:

  • ChargesController#create 变量 @pin 未初始化 (@pin == nil)。您需要添加 @pin = Pin.find(params[:id])@pin = Pin.build(...) 之类的内容。
  • 刚刚用@pin = Pin.find(params[:id]) 初始化了变量并收到错误消息:“找不到没有ID的Pin”。不确定,为什么会这样?
  • 你只需要找出@pin是什么。您是创建它还是从数据库中检索它?如果您的模型/控制器中有更多代码,我可以更具体。

标签: ruby-on-rails ruby stripe-payments


【解决方案1】:

问题是在您的费用控制器中@pin 没有分配给任何东西,因此具有nil 的值因此错误。

因此,您需要在调用 price 之前将 @pin 分配给一个值。为此,您需要弄清楚如何从 DB 中获取 pin 或是否创建它。

一种解决方案可能是在请求路径中传递 pin 的 id,例如

create_charge_path(pin_id: 123) 

编辑:这不必硬编码为 123,它可以是你喜欢的任何引脚,只取决于它被调用的位置。例如。如果您从另一个已经从数据库加载特定引脚的控制器操作调用,您可以这样做:

create_charge_path(pin_id: pin.id)

然后在你的ChargesController

class ChargesController < ApplicationController

    def create
      @pin = Pin.find(params[:pin_id])
      # Amount in cents
      @amount = (@pin.price * 100).floor

      customer = Stripe::Customer.create(
        :email => params[:stripeEmail],
        :card  => params[:stripeToken]
      )

      charge = Stripe::Charge.create(
        :customer    => customer.id,
        :amount      => @amount,
        :description => 'Rails Stripe customer',
        :currency    => 'usd'
      )

    rescue Stripe::CardError => e
      flash[:error] = e.message
      redirect_to charges_path
    end
end

这会将@pin 分配给数据库ID 为123 的引脚。

【讨论】:

  • 在请求路径中你会在哪里传递 pin 的 id?我正在尝试查看是否有一种更具可扩展性的方法来执行此操作,而不是将 @pin 及其所有实例分配给数据库中的一个 id。
  • 因此,无论是调用 ChargesController#create 方法的方法、按钮还是链接,您都可以在其中传递 PIN ID。此外,这不会是全局分配 - 它只会将 @pin 分配给传入的 pin id。请参阅我的编辑以进行澄清
  • 所以由于某种原因这不起作用。我相信我已经使用调用 ChargesController 的按钮添加了更多代码 - 不确定我是否可以使用您推荐的路径添加另一个隐藏字段文本。
猜你喜欢
  • 2017-08-10
  • 2013-07-31
  • 2022-08-13
  • 2011-07-27
  • 2013-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多