【问题标题】:Undefined method 'suspend_paypal' for User用户的未定义方法“suspend_paypal”
【发布时间】:2019-11-03 16:41:14
【问题描述】:

我正在为我的应用程序使用paypal-recurring gem,但我不知道如何取消用户的订阅。我在这里的一个类似问题中尝试了 gabriel 的 answer,但是在尝试取消订阅时,我在 SubscriptionsController#suspend undefined method 'suspend_paypal' for User` 中得到一个 NoMethodError' .

在我的 subscriptions.rb 模型中

class Subscription < ApplicationRecord

  belongs_to :plan
  belongs_to :user
  validates_presence_of :plan_id
  validates_presence_of :user_id
  attr_accessor :paypal_payment_token

def save_with_payment
  if valid?
    if paypal_payment_token.present?
      save_with_paypal_payment
    end
  end

end

def paypal
  PaypalPayment.new(self)
end

def save_with_paypal_payment
  response = paypal.make_recurring
  self.paypal_recurring_profile_token = response.profile_id
  save!
end




def suspend_paypal
  paypal.suspend
  self.status = "canceled"
  save
end



def payment_provided?
paypal_payment_token.present?
end
end

订阅控制器

    class SubscriptionsController < ApplicationController
      before_action :authenticate_user! , only: [:new,  :edit]

    def new
      plan = Plan.find(params[:plan_id])
      @subscription = plan.subscriptions.build
      @subscription.user_id = current_user.id
      if params[:PayerID]
        @subscription.paypal_cutomer_token = params[:PayerID]
        @subscription.paypal_payment_token = params[:token]
        @subscription.email = @subscription.paypal.checkout_details.email
      end
    end

    def index
    end



    def create

      @user = current_user

        @subscription = Subscription.new(subscription_params)
      if @subscription.save_with_payment
        redirect_to root_path, :notice => "Thank you for subscribing"
        @user.premium!
      else
        render :new
      end
    end


    def suspend
     @user = current_user
     @user.suspend_paypal
     flash[:success] = 'Subscription Canceled.'
     @user.free!
     redirect_to root_path
    end


    def show
      @subscription = Subscription.find(params[:id])
    end

    def paypal_checkout
      plan = Plan.find(params[:plan_id])
      subscription = plan.subscriptions.build
      redirect_to subscription.paypal.checkout_url(
        return_url: new_subscription_url(:plan_id => plan.id),
        cancel_url: root_url,
      )
    end


    private

    def subscription_params
      params.require(:subscription).permit!
    end

end

paypal_payment.rb

  class PaypalPayment
def initialize(subscription)
    @subscription = subscription
  end

def checkout_details
process :checkout_details
end


def payment_active?
  self.status = "active"
  end

  def suspend
       process :suspend, :profile_id => @subscription.paypal_recurring_profile_token
   end
def checkout_url(options)
  process(:checkout, options).checkout_url
end

def save_with_paypal_payment
  response = paypal.make_recurring
  self.paypal_recurring_profile_token = response.profile_id
  save!

end



def make_recurring
  process :request_payment
  process :create_recurring_profile, period: :monthly, frequency: 1, start_at: Time.zone.now
end

private

def process(action, options = {})
  options = options.reverse_merge(
  token: @subscription.paypal_payment_token,
  payer_id: @subscription.paypal_cutomer_token,
  description: @subscription.plan.name,
  amount: @subscription.plan.price,
  currency: "USD"



  )
  response = PayPal::Recurring.new(options).send(action)
  raise response.errors.inspect if response.errors.present?
  response


end

end

查看

<%= link_to "Suspend paypal", subscriptions_suspend_path, :data => { :confirm => "Are you sure?" } %>

【问题讨论】:

    标签: ruby-on-rails paypal paypal-rest-sdk paypal-subscriptions recurring-billing


    【解决方案1】:

    您在Subscription 模型上定义了suspend_paypal,但您正试图在用户上调用它。获取订阅并调用方法:

    # class SubscriptionsController
    
    def suspend
       @subscription = Subscription.find(params[:id])
       @subscription.suspend_paypal
       flash[:success] = 'Subscription Canceled.'
       current_user.free!
       redirect_to root_path
    end
    

    注意——您应该添加授权逻辑,否则任何可以进行身份​​验证的用户都可以通过发送其 ID 来暂停任意订阅。如果用户has_many 订阅,subscription = current_user.subscriptions.find(params[:id])。如果has_one,只需current_user.subscription 并验证它是否与params[:id] 相匹配。

    您可能也不需要 subscription 成为 ivar,因为您只是重定向到 root。只需将@subscription 替换为subscription。当您需要访问视图中的这些变量时,请使用 ivars。

    【讨论】:

    • 现在出现此错误“找不到没有 ID 的订阅”。
    • 您指向 subscriptions_suspend_path 的链接未指定 ID。 routes.rb中的路由是怎么定义的? collection 路由?路由需要与特定的用户或订阅 id 相关联,否则它如何知道要取消哪个订阅?将路由定义为成员路由并使用subscriptions_suspend_path(PUT_SUBSCRIPTION_OBJECT_HERE),或将相关 id 传递给该路由的参数的类似方法。
    猜你喜欢
    • 1970-01-01
    • 2014-07-31
    • 2016-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 2012-11-06
    相关资源
    最近更新 更多