title: Stack level too deep in Ruby in subscription model
body: <p>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". </p>
  
  <p>I have installed the koudoku gem. </p>
  
  <p>I have a merchant model and a subscription model. All I did was add 2 lines of codes to the subscription model.</p>
  
  <p>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?</p>
  
  <p>I have added the 2 lines here.</p>
  
  <pre><code>      # 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
  </code></pre>
  
  <p>And here.</p>
  
  <pre><code># 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
  </code></pre>
  
  <p>Here's the whole code to subscription model.</p>
  
  <pre><code>class Subscription &lt; 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 =&gt; self.plan.stripe_id, :prorate =&gt; 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 =&gt; self.plan.stripe_id, :prorate =&gt; Koudoku.prorate)
  
          rescue Stripe::CardError =&gt; card_error
            errors[:base] &lt;&lt; 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
  </code></pre>
  
  <p>Here's the merchant model.</p>
  
  <pre><code>class Merchant &lt; 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
  </code></pre>
  
  <p>And here's my error logs.</p>
  
  <pre><code>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!
  </code></pre>
  
  <p>And repeats.</p>