【问题标题】:Rails 3: Instance variable not working as charge amount for Stripe?Rails 3:实例变量不能作为 Stripe 的收费金额?
【发布时间】:2012-08-09 21:52:31
【问题描述】:

我正在将 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

我在这里做错了什么?

【问题讨论】:

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


    【解决方案1】:

    我猜,控制器实例变量在模型中不可用。检查发布到此问题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
    

    【讨论】:

    • 我在上面添加了我的完整代码...我将如何实现您在我的控制器中提供的示例?
    • Kulbir,给你+1的答案,我们几乎同时得出了相同的结论。
    • @n0denine 是的,只需几秒钟 :)
    【解决方案2】:

    我不确定,因为我看不到您的模型代码,但我怀疑这是因为您没有为 :total 设置 attr_accessor,所以 attr_accessor :total 在模态中看看会发生什么。除非我对您的付款流程的结构有更好的想法(请参阅您的代码),否则我无法就此事给出可靠的答案。您可以查看http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/,看看您是否找到适合您的东西。

    编辑

    虽然您在谈论模型实例变量,但您必须将实例变量从控制器传递给模型。下面是一个例子。

    控制器sn-p

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

    型号sn-p

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

    【讨论】:

    • 我添加了完整的模型和控制器代码。我尝试添加 :total 属性,但它没有改变任何东西。有什么想法吗?
    • 哦,兄弟你得把总变量从控制器发送到模型内部的实例方法。查看我的帖子编辑,它应该会在一分钟内显示出来
    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 2015-06-28
    • 2017-07-10
    • 1970-01-01
    • 2017-07-18
    • 2013-07-23
    • 2019-12-17
    • 2016-04-29
    相关资源
    最近更新 更多