1

我正在将 Stripe 添加到我的 Rails 3 应用程序以接受信用卡付款,并且我正在尝试使用实例变量“@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,所以 attr_accessor :total 在模态中看看会发生什么。除非我对您的付款流程的结构有更好的想法(请参阅您的代码),否则我无法就此事给出可靠的答案。您可以查看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 回答