我已将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
我在这里做错了什么?
答案 0 :(得分:2)
我猜,控制器实例变量在模型中不可用。检查发布到此问题的解决方案Ruby on Rails - Access controller variable from model。
<强>更新强>
您无需遵循网址中提到的示例。您可以直接将@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
答案 1 :(得分:1)
我不确定,因为我看不到你的模型代码,但我怀疑这是因为你没有设置attr_accessor:total,所以attr_accessor:模态中的总数,看看会发生什么。除非我对您的付款流程的结构有更好的了解(请参阅您的代码),否则我无法就此事给出一个可靠的答案。您可以查看http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/以查看是否找到适合您的内容。
修改强>
我虽然你在谈论模型实例变量,但你必须将实例变量从控制器传递给模型。以下是一个例子。
Controller snippet
...
@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