1

個人情報とクレジット カード情報を入力するユーザー サインアップ ページがあります。ユーザーには has_many のアカウントがあり、アカウントはユーザーに属しています。ユーザーが作成されると、アカウントが作成され、クレジット カード情報と住所がサブスクリプション テーブルに格納されます。アカウント作成後、subscription.rbモデルのstore_cardメソッドへ。Rails 3.2.13 でアプリケーションを実行すると正常に動作し、Rails 4.2.6 に移行すると、サブスクリプションの詳細が保存されず、エラーも表示されません。activemerchant gem を 1.47.0 にアップグレードし、以下のコントローラーの load_billing メソッドのコードを

@creditcard = ActiveMerchant::Billing::CreditCard.new(params[:account].blank? ? nil : params[:account][:creditcard])

@creditcard = ActiveMerchant::Billing::CreditCard.new(params[:account].blank? ? {} : params[:account][:creditcard])

@address も同様です。

特定の関係はありませんが、account.rb に次の行を追加するだけです。

has_subscription :user_limit => Proc.new {|a| a.users.count }

コンソールから実行しようとしたとき:

u = Account.find(1)
u.subscription 

サブスクリプション列を生成しています。

class AccountsController < ApplicationController

  before_filter :build_account, :only => [:new, :create]
  before_filter :build_user, :only => [:new, :create]
  before_filter :load_billing, :only => [:new, :create, :billing]
  def create
    @address.first_name = @creditcard.first_name
    @address.last_name = @creditcard.last_name
    @account.address = @address
    @account.creditcard = @creditcard
    if @account.new_record?
      if @account.save
        flash[:notice] = 'Account was created.'
        bypass_sign_in(@user)
        redirect_to session[:previous_url] || user_reports_path(@user)
      else
        render :action => 'new'
      end
    else
      @user.account_id = @account.id
      if @user.save
        flash[:notice] = 'User was created.'
        bypass_sign_in(@user)
        redirect_to session[:previous_url] || user_reports_path(@user)
      else
        render :action => 'new'
      end
    end
  end

  def billing
    @user = current_user
    @account = Account.find(params[:id])
    if request.put?
      @address.first_name = @creditcard.first_name
      @address.last_name = @creditcard.last_name
      puts @address.first_name
      if @creditcard.valid? & @address.valid?
       if @subscription.store_card(@creditcard, :billing_address => @address.to_activemerchant, :ip => request.remote_ip)
         flash[:notice] = "Your billing information has been updated."
         redirect_to settings_path(@user)
       end
      end
    end
  end
  protected

  def resource
    @account ||= current_account
  end

  def build_account
    @account = params[:account_name].blank? ? Account.new : Account.find_by_name(params[:account_name])
  end

  def build_user
    @account.user = @user = User.new(params[:account].blank? ? nil : params[:account][:user])
  end

  def load_billing
    @creditcard = ActiveMerchant::Billing::CreditCard.new(params[:account].blank? ? {} : params[:account][:creditcard])
    @address = SubscriptionAddress.new(params[:account].blank? ? {} : params[:account][:address])
  end

end

サブスクリプション.rb:

class Subscription < ActiveRecord::Base

  attr_accessor :creditcard, :address
  def store_card(creditcard, gw_options = {})
    # Clear out payment info if switching to CC from PayPal
    destroy_gateway_record(paypal) if paypal?

    @response = if billing_id.blank?
      gateway.store(creditcard, gw_options)
    else
      gateway.update(billing_id, creditcard, gw_options)
    end

    if @response.success?
      if active_card = @response.params['active_card']
        # Stripe token-based response
        self.card_number = "XXXX-XXXX-XXXX-#{active_card['last4']}"
        self.card_expiration = "%02d-%d" % [active_card['exp_month'], active_card['exp_year']]
      else
        self.card_number = creditcard.display_number
        self.card_expiration = "%02d-%d" % [creditcard.expiry_date.month, creditcard.expiry_date.year]
      end
      set_billing
    else
      errors.add(:base, @response.message)
      false
    end
  end

  def card_storage
      self.store_card(@creditcard, :billing_address => @address.to_activemerchant) if @creditcard && @address && card_number.blank?
    end

  def set_billing
      self.billing_id = @response.token
    end

end

アカウント.rb:

class Account < ActiveRecord::Base

validate :valid_subscription?, :on => :create

  def valid_subscription?
    puts "valid_subscription**************************"
    return if errors.any? # Don't bother with a subscription if there are errors already
    self.build_subscription(:plan => @plan, :next_renewal_at => @plan_start, :creditcard => @creditcard, :address => @address)
    if !subscription.valid?
      errors.add(:base, "Error with payment: #{subscription.errors.full_messages.to_sentence}")
      return false
    end
  end
end

強力なパラメーターを使用する必要があるかどうか、およびどのようにまたは他の方法で使用する必要があるかどうかを助けてください。

4

1 に答える 1

0

モデルも表示するのは良いことAccountですが、コードに基づいて、クレジット カード情報を保存していないように見えます。メソッドstore_cardは値を割り当てるだけで、データベースに保存することはありません。self.save最も簡単な解決策は、store_cardメソッドを呼び出すだけです。

 if active_card = @response.params['active_card']
    # Stripe token-based response
    self.card_number = "XXXX-XXXX-XXXX-#{active_card['last4']}"
    self.card_expiration = "%02d-%d" % [active_card['exp_month'], active_card['exp_year']]
  else
    self.card_number = creditcard.display_number
    self.card_expiration = "%02d-%d" % [creditcard.expiry_date.month, creditcard.expiry_date.year]
  end
  self.save
于 2016-07-10T22:10:48.320 に答える