2016-06-22 7 views
0

ストライプ支払いのテストを行っているアプリケーションがあります。今、私は別のモデル(pin.price)から価格を取り、正しく請求するように料金を設定しようとしています。これまでのところ、私は、次のエラーメッセージに実行しています:NilClassストライプ支払い:未定義のメソッド `price 'for nil:NilClass

アプリ/コントローラ/ 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 
:ChargesController#で

NoMethodError nilのための 未定義のメソッド `価格」を作成

アプリ/コントローラ/ 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 

アプリ/ DB /移行

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

私はエラーがから来ているかなり確信している「@amount =(@ pin.price * 100).floor」が、私はちょうど良くて、各ピンの価格ISN」は、この量を表現する方法がわかりませんt staticであるが、データベースの現在の入力値と一致する。

編集:ここでは、ストライプの支払いコードへのリンクを持つフォームを含む:

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

任意の考え?

+0

'ChargesController#create'変数' @ pin'は初期化されていません( '@pin == nil')。 '@pin = Pin.find(params [:id])'や '@pin = Pin.build(...)'のようなものを追加する必要があります。 –

+0

@pin = Pin.find(params [:id])で変数を初期化し、 "IDなしのピンを見つけることができませんでした"というエラーメッセージが表示されます。確かに、なぜこれは起こっているのですか? –

+0

'@pin'が何であるか調べるだけです。それを作成するのか、データベースから取得しますか?あなたのモデル/コントローラからより多くのコードがあれば、より具体的にすることができます。 –

答えて

1

あなたの料金コントローラでは、@pinに何も割り当てられていないため、値がnilであるため、エラーです。

したがって、価格を呼び出す前に@pinに値を割り当てる必要があります。これを行うには、DBからピンを取得する方法、またはピンを作成するかどうかを判断する必要があります。

解決策の1つは、要求パスのピンのIDを渡すことです。

create_charge_path(pin_id: 123) 

EDIT:これはちょうどそれがから呼び出されています場所によって異なり、それはあなたが好きなピンすることができ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です。

+0

リクエストパスのピンのIDはどこに渡しますか? @pinとそのすべてのインスタンスをデータベース内の1つのidに割り当てるのではなく、これを行うためのスケーラブルな方法があるかどうかを確認しようとしています。 –

+0

だから、どのような方法、またはボタンやリンクがChargesController#はあなたがPIN IDで通過するところである方法を、作成呼び出します。また、これはグローバルな割り当てではなく、渡されたピンidにのみ '@ pin 'を割り当てます。明確化のために私の編集を参照してください –

+0

何らかの理由でこれは動作していません。私はChargesControllerを呼び出すボタンでコードを追加しましたが、あなたが推奨するパスで別の隠しフィールドテキストを追加してもうまくいかないかは確信しています。 –

関連する問題