简体   繁体   中英

Stack level too deep in Ruby in subscription model

I'm a noob in RoR and I hope someone could help me point me to the right direction with this? The error log says "stack level too deep".

I have installed the koudoku gem.

I have a merchant model and a subscription model. All I did was add 2 lines of codes to the subscription model.

It works fine when a plan is upgraded or downgraded but not when a user signs up for a new plan. How do I solve this?

I have added the 2 lines here.

      # and a customer exists in stripe ..
      if stripe_id.present?

      # fetch the customer.
      customer = Stripe::Customer.retrieve(self.stripe_id)

      # if a new plan has been selected
      if self.plan.present?

        # Record the new plan pricing.
        self.current_price = self.plan.price
         merchant.role = Merchant.roles[plan.stripe_id]
         merchant.save

And here.

# when customer DOES NOT exist in stripe ..
else

  # if a new plan has been selected
  if self.plan.present?

    # Record the new plan pricing.
    self.current_price = self.plan.price
    merchant.role = Merchant.roles[plan.stripe_id]
    merchant.save

Here's the whole code to subscription model.

class Subscription < ActiveRecord::Base
include Koudoku::Subscription

belongs_to :merchant
belongs_to :coupon

def processing!

  # if their package level has changed ..
  if changing_plans?

    prepare_for_plan_change

    # and a customer exists in stripe ..
    if stripe_id.present?

      # fetch the customer.
      customer = Stripe::Customer.retrieve(self.stripe_id)

      # if a new plan has been selected
      if self.plan.present?

        # Record the new plan pricing.
        self.current_price = self.plan.price
         merchant.role = Merchant.roles[plan.stripe_id]
         merchant.save

        prepare_for_downgrade if downgrading?
        prepare_for_upgrade if upgrading?

        # update the package level with stripe.
        customer.update_subscription(:plan => self.plan.stripe_id, :prorate => Koudoku.prorate)

        finalize_downgrade! if downgrading?
        finalize_upgrade! if upgrading?

      # if no plan has been selected.
      else

        prepare_for_cancelation

        # Remove the current pricing.
        self.current_price = nil

        # delete the subscription.
        customer.cancel_subscription

        finalize_cancelation!

      end

    # when customer DOES NOT exist in stripe ..
    else

      # if a new plan has been selected
      if self.plan.present?

        # Record the new plan pricing.
        self.current_price = self.plan.price
        merchant.role = Merchant.roles[plan.stripe_id]
        merchant.save

        prepare_for_new_subscription
        prepare_for_upgrade

        begin
          raise Koudoku::NilCardToken, "Possible javascript error" if credit_card_token.empty?
          customer_attributes = {
            description: subscription_owner_description,
            email: subscription_owner_email,
            card: credit_card_token, # obtained with Stripe.js
          }


          # If the class we're being included in supports coupons ..
          if respond_to? :coupon
            if coupon.present? and coupon.free_trial?
              customer_attributes[:trial_end] = coupon.free_trial_ends.to_i
            end
          end

          customer_attributes[:coupon] = @coupon_code if @coupon_code

          # create a customer at that package level.
          customer = Stripe::Customer.create(customer_attributes)

          finalize_new_customer!(customer.id, plan.price)
          customer.update_subscription(:plan => self.plan.stripe_id, :prorate => Koudoku.prorate)

        rescue Stripe::CardError => card_error
          errors[:base] << card_error.message
          card_was_declined
          return false
        end

        # store the customer id.
        self.stripe_id = customer.id
        self.last_four = customer.cards.retrieve(customer.default_card).last4

        finalize_new_subscription!
        finalize_upgrade!

      else

        # This should never happen.

        self.plan_id = nil

        # Remove any plan pricing.
        self.current_price = nil

      end


    finalize_plan_change!
    end

  # if they're updating their credit card details.
  elsif self.credit_card_token.present?

    prepare_for_card_update

    # fetch the customer.
    customer = Stripe::Customer.retrieve(self.stripe_id)
    customer.card = self.credit_card_token
    customer.save

    # update the last four based on this new card.
    self.last_four = customer.cards.retrieve(customer.default_card).last4
    finalize_card_update!

  end
end
end


 def describe_difference(plan_to_describe)
if plan.nil?
  if persisted?
    I18n.t('koudoku.plan_difference.upgrade')
  else
    if Koudoku.free_trial?
      I18n.t('koudoku.plan_difference.start_trial')
    else
      I18n.t('koudoku.plan_difference.upgrade')
    end
  end
else
  if plan_to_describe.is_upgrade_from?(plan)
    I18n.t('koudoku.plan_difference.upgrade')
  else
    I18n.t('koudoku.plan_difference.downgrade')
  end
end

end

Here's the merchant model.

class Merchant < ActiveRecord::Base
# Added by Koudoku.
has_one :subscription

# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

enum role: [:free, :basic, :basic_plus, :pair, :bundle, :admin]


end

And here's my error logs.

activerecord (4.2.5) lib/active_record/attribute.rb:29:in `initialize'
activerecord (4.2.5) lib/active_record/attribute.rb:9:in `new'
activerecord (4.2.5) lib/active_record/attribute.rb:9:in `from_user'
activerecord (4.2.5) lib/active_record/attribute.rb:58:in `with_value_from_user'
activerecord (4.2.5) lib/active_record/attribute_set.rb:39:in `write_from_user'
activerecord (4.2.5) lib/active_record/attribute_methods/write.rb:74:in `write_attribute_with_type_cast'
activerecord (4.2.5) lib/active_record/attribute_methods/write.rb:56:in `write_attribute'
activerecord (4.2.5) lib/active_record/attribute_methods/dirty.rb:96:in `write_attribute'
activerecord (4.2.5) lib/active_record/attribute_methods.rb:373:in `[]='
devise (4.2.1) lib/devise/models/authenticatable.rb:207:in `apply_to_attribute_or_variable'
devise (4.2.1) lib/devise/models/authenticatable.rb:198:in `block in downcase_keys'
devise (4.2.1) lib/devise/models/authenticatable.rb:198:in `each'
devise (4.2.1) lib/devise/models/authenticatable.rb:198:in `downcase_keys'
activesupport (4.2.5) lib/active_support/callbacks.rb:432:in `block in make_lambda'
activesupport (4.2.5) lib/active_support/callbacks.rb:164:in `block in halting'
activesupport (4.2.5) lib/active_support/callbacks.rb:504:in `block in call'
activesupport (4.2.5) lib/active_support/callbacks.rb:504:in `each'
activesupport (4.2.5) lib/active_support/callbacks.rb:504:in `call'
activesupport (4.2.5) lib/active_support/callbacks.rb:92:in `__run_callbacks__'
activesupport (4.2.5) lib/active_support/callbacks.rb:778:in `_run_validation_callbacks'
activemodel (4.2.5) lib/active_model/validations/callbacks.rb:113:in `run_validations!'
activemodel (4.2.5) lib/active_model/validations.rb:337:in `valid?'
activerecord (4.2.5) lib/active_record/validations.rb:58:in `valid?'
activerecord (4.2.5) lib/active_record/validations.rb:83:in `perform_validations'
activerecord (4.2.5) lib/active_record/validations.rb:37:in `save'
activerecord (4.2.5) lib/active_record/attribute_methods/dirty.rb:21:in `save'
activerecord (4.2.5) lib/active_record/transactions.rb:286:in `block (2 levels) in save'
activerecord (4.2.5) lib/active_record/transactions.rb:351:in `block in with_transaction_returning_status'
activerecord (4.2.5) lib/active_record/connection_adapters/abstract/database_statements.rb:211:in `transaction'
activerecord (4.2.5) lib/active_record/transactions.rb:220:in `transaction'
activerecord (4.2.5) lib/active_record/transactions.rb:348:in `with_transaction_returning_status'
activerecord (4.2.5) lib/active_record/transactions.rb:286:in `block in save'
activerecord (4.2.5) lib/active_record/transactions.rb:301:in `rollback_active_record_state!'
activerecord (4.2.5) lib/active_record/transactions.rb:285:in `save'
app/models/subscription.rb:61:in `processing!

And repeats.

I have solved the problem just by adding an after_commit callback to set the roles.

Here's the updated code in the subscription model.

after_commit :set_merchant_role

def set_merchant_role
  merchant.role = Merchant.roles[plan.stripe_id]
  merchant.save
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM