1

Rails 3 アプリに Stripe を追加してクレジット カードでの支払いを受け入れ、顧客に請求する金額に "@total" というインスタンス変数を使用しようとしています。

現在、モデルにあるものは次のとおりです。

class Video < ActiveRecord::Base
  attr_accessible :age, :category, :description, :ethnicity, :gender, :genre, :interest, :length, :panda_video_id, :size, :tagline, :title, :video_id, :stripe_card_token
  attr_writer :current_step
  attr_accessor :stripe_card_token
  serialize :size
  serialize :age
  serialize :gender
  serialize :ethnicity

  has_many :audiences, :dependent => :destroy
  accepts_nested_attributes_for :audiences, :allow_destroy => true

  #validates_presence_of :panda_video_id, :if => lambda { |o| o.current_step == "upload" }

  def panda_video
    @original_video ||= Panda::Video.find(panda_video_id)
  end

  def save_with_payment
  if valid?
    charge = Stripe::Charge.create(
    amount: @total,
    currency: "usd",
    card: stripe_card_token
    )
  end
rescue Stripe::InvalidRequestError => e
  logger.error "Stripe error while creating charge: #{e.message}"
  errors.add :base, "There was a problem with your credit card."
  false
end

  def current_step
    @current_step || steps.first
  end

  def steps
    %w[upload info audience review]
  end

  def next_step
    self.current_step = steps[steps.index(current_step)+1]
  end

  def previous_step
    self.current_step = steps[steps.index(current_step)-1]
  end

  def first_step?
    current_step == steps.first
  end

  def last_step?
    current_step == steps.last
  end

  def all_valid?
    steps.all? do |step|
        self.current_step = step
        valid?
    end
  end
end

Stripe サポートに連絡したところ、インスタンス変数はここで動作するはずだと言われました。したがって、問題はコントローラーにあると思われます。

class VideosController < ApplicationController
  def index
    @videos = Video.all
  end

  def show
    @video = Video.find(params[:id])
    @original_video = @video.panda_video
    @h264_encoding = @original_video.encodings["h264"]
  end

  def new
    session[:video_params] ||= {}
    @video = Video.new(session[:video_params])
    @video.current_step = session[:video_step]
  end

  def create
    session[:video_params].deep_merge!(params[:video]) if params[:video]

    #Save total value and audience form to session.
    @total = session[:video_params]["size"].collect(&:to_i).sum - 10 if session[:video_params]["size"]
    @audiences = session[:video_params].slice("size", "gender", "age", "ethnicity").to_json

    @video = Video.new(session[:video_params])
    @video.current_step = session[:video_step]
    if @video.valid?
        if params[:back_button]
            @video.previous_step
        elsif @video.last_step?
            @video.save if @video.all_valid? && @video.save_with_payment
        else
            @video.next_step
        end
        session[:video_step] = @video.current_step
    end
    if @video.new_record?
        render "new"
    else
        session[:video_step] = session[:video_params] = nil
        flash[:notice] = "Video saved"
        redirect_to @video
    end
  end

  def edit
    @video = Video.find(params[:id])
  end

  def update
    @video = Video.find(params[:id])
    if @video.update_attributes(params[:video])
      redirect_to @video, :notice  => "Successfully updated video."
    else
      render :action => 'edit'
    end
  end

  def destroy
    @video = Video.find(params[:id])
    @video.destroy
    redirect_to videos_url, :notice => "Successfully destroyed video."
  end
end

私の Rails アプリはマルチステップ フォームで、すべてのデータがセッションに保存されます。@total は、フォームのオーディエンス ステップの入力値を合計し、その @total 数値が、顧客が支払い情報を入力する最終ステップに表示されます。@total 数は現在このページに表示されていますが、何らかの理由で Stripe が処理できません。次のエラーが発生し続けるためです。

Stripe error while creating charge: Missing required param: amount

ここで何が間違っていますか?

4

2 に答える 2

2

コントローラーのインスタンス変数はモデルでは使用できないと思います。この質問Ruby on Rails - Access controller variable from model に投稿された解決策を確認してください。

アップデート

URL に記載されている例に従う必要はありません。@totalこのように変数を引数として直接渡すことができます

#model
def save_with_payment(total)
  ...
  charge = Stripe::Charge.create(
  amount: total,
  currency: "usd",
  card: stripe_card_token
  )
  ...
end

# controller

def create
...
    if params[:back_button]
        @video.previous_step
    elsif @video.last_step?
        @video.save if @video.all_valid? && @video.save_with_payment(@total)
    else
        @video.next_step
    end
...
end
于 2012-08-13T16:31:54.720 に答える
1

モデル コードが表示されないためわかりませんが、:total に attr_accessor が設定されていないためだと思われます。あなたの支払いプロセスがどのように構成されているかについて、私がより良い考えを持っていない限り(あなたのコードを参照してください)、私はこの問題について確かな答えを出すことはできません. http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/をチェックして、自分に合ったものが見つかるかどうかを確認してください。

編集

モデルのインスタンス変数について話していましたが、コントローラーからモデルにインスタンス変数を渡す必要があります。以下は例です。

コントローラーのスニペット

...
@video.save if @video.all_valid? && @video.save_with_payment(@total)
...

モデル スニペット

...
def save_with_payment(total)
 if valid?
  charge = Stripe::Charge.create(
   amount: total,
   currency: "usd",
   card: stripe_card_token
  )
end
于 2012-08-13T16:22:21.237 に答える