Rails 3: переменная экземпляра не работает как сумма заряда для Stripe?

Я добавляю 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

Приложение My rails представляет собой многоэтапную форму, в которой все данные хранятся в сеансе. @total суммирует входные значения на этапе аудитории формы, а затем это число @total отображается на последнем этапе, где покупатель вводит свою платежную информацию. Номер @total в настоящее время отображается на этой странице, но по какой-то причине Stripe не может его обработать, так как я продолжаю получать следующую ошибку:

Stripe error while creating charge: Missing required param: amount

Что я здесь делаю не так?


person user1429496    schedule 13.08.2012    source источник


Ответы (2)


Я не уверен, потому что я не вижу код вашей модели, но подозреваю, что это потому, что у вас нет attr_accessor для: total, поэтому 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
person n0denine    schedule 13.08.2012
comment
Я добавил свою полную модель и код контроллера. Я попытался добавить атрибут: total, но ничего не изменилось. Любые идеи? - person user1429496; 13.08.2012
comment
О, брат, тебе нужно отправить общую переменную из контроллера в метод экземпляра внутри модели. см. мой пост, он должен появиться через минуту - person n0denine; 13.08.2012

Я предполагаю, что переменные экземпляра контроллера недоступны в моделях. Проверьте решение, опубликованное по этому вопросу Ruby on Rails - переменная контроллера доступа из модели.

ОБНОВЛЕНИЕ

Вам не нужно следовать примеру, упомянутому в 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
person Kulbir Saini    schedule 13.08.2012
comment
Я добавил свой полный код выше ... как мне реализовать приведенный вами пример в моем контроллере? - person user1429496; 13.08.2012
comment
Кульбир, дал вам +1 за ответ, мы пришли к такому же выводу почти одновременно. - person n0denine; 15.08.2012
comment
@ n0denine да, считанные секунды :) - person Kulbir Saini; 16.08.2012