0

I have a Rails app in development that allows for premium membership signups with Stripe and, as one would expect, the ability to cancel that membership. In order to cancel membership, users click a button that triggers the destroy action in the Promembers_controller.rb. Inside destroy there's a call to an instance method cancel_subscription that, together with some JavaScript, handles the cancellation of the membership with Stripe, by calling customer.cancel_subscription. Checking my Stripe test records, the memberships are being cancelled, however, it seems as if the method cancel_subscription is returning false, because this unsuccessful redirect keeps getting run

redirect_to (:back),  :notice => "Not successful. Please try again or contact us."

and the rest of the code in the destroy action (i.e. after @promember.cancel_subscription(id) is not getting run.

Question: (this is borrowed code). Is the cancel_subscription method such that the false at the end of the rescue will always be returned (even if there's no rescue taking place) and is that why the redirect in the else clause of the destroy action is always getting called? What is a better way to achieve what I'm trying to do?

Promembers_controller.rb

    def destroy
        id = current_user.customer_id
        @promember = current_user.promember

        if @promember.cancel_subscription(id)
              session[:pro] = nil

        current_user.customer_id = nil   #is not getting run
        current_user.promember.delete    #is not getting run
        current_user.last_four_digits = nil  #is not getting run
        current_user.save

            redirect_to lawyer_profile_path(current_user), :notice => "Premium membership has been cancelled."

        else 
            redirect_to (:back),  :notice => "Not successful. Please try again or contact us."
        end 

    end 

Promember.rb

def cancel_subscription(customer_id)
      unless customer_id.nil?
        customer = Stripe::Customer.retrieve(customer_id)
          unless customer.nil? or customer.respond_to?('deleted')          
              if customer.subscription.status == 'active'
                customer.cancel_subscription
                user.remove_role :pro 
                  if user.practices.size > 1                   
                    user.practices.delete(user.practices[1])
                  end               
              end
          end
      end
    rescue Stripe::StripeError => e
      logger.error "Stripe Error: " + e.message
      errors.add :base, "Unable to cancel your subscription. #{e.message}."
      false
  end
4

1 回答 1

-1

false末尾的导致cancel_subscription隐式返回。基本上,在 Ruby 中,如果不存在 return 语句,则方法将返回最终语句的结果。在这种情况下,它相当于return false。您可以尝试return true在这样的适当位置添加 a ,因为您希望在删除成功时返回 true 。

def cancel_subscription(customer_id)
  unless customer_id.nil?
    customer = Stripe::Customer.retrieve(customer_id)
      unless customer.nil? or customer.respond_to?('deleted')          
          if customer.subscription.status == 'active'
            customer.cancel_subscription
            user.remove_role :pro 
              if user.practices.size > 1                   
                user.practices.delete(user.practices[1])
                return true
              end               
          end
      end
  end
  rescue Stripe::StripeError => e
    logger.error "Stripe Error: " + e.message
    errors.add :base, "Unable to cancel your subscription. #{e.message}."
    false
end
于 2013-06-13T20:44:18.593 回答