Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails ActiveRecord方法中对数据库的意外第二次调用_Ruby On Rails_Activerecord_Callback - Fatal编程技术网

Ruby on rails ActiveRecord方法中对数据库的意外第二次调用

Ruby on rails ActiveRecord方法中对数据库的意外第二次调用,ruby-on-rails,activerecord,callback,Ruby On Rails,Activerecord,Callback,我试图实现一个功能,用户可以使用订阅代码注册订阅。这是我的代码: class SubscriptionsController < ApplicationController def create @subscription = current_user.subscriptions.build(subscription_params) respond_to do |format| if @subscription.save

我试图实现一个功能,用户可以使用订阅代码注册订阅。这是我的代码:

 class SubscriptionsController < ApplicationController

    def create
      @subscription = current_user.subscriptions.build(subscription_params)



      respond_to do |format|
        if @subscription.save
          format.html { redirect_to @subscription, notice: 'Subscription was successfully created.' }
          format.json { render :show, status: :created, location: @subscription }
        else
          format.html { render :new }
          format.json { render json: @subscription.errors, status: :unprocessable_entity }
        end
      end
    end
  end



 class Subscription < ActiveRecord::Base
  belongs_to :user
  belongs_to :topic
  has_one :subscription_code
  before_validation :register_subscription
  after_save :register_expiry_date
  validates_presence_of :submitted_code, :topic_id, :subscription_code_id

  attr_accessor :submitted_code

  private

    def register_subscription

      registered_code_id = SubscriptionCode.register_subscription_code(self.submitted_code)

      unless registered_code_id == nil
        self.subscription_code_id = registered_code_id
      else
        errors.add(:submitted_code, "Invalid Code")
        return false
      end
    end

    def register_expiry_date
      self.expiry_date ||= self.created_at + 1.year
      self.save
    end
end



class SubscriptionCode < ActiveRecord::Base
  belongs_to :subscription
  attr_accessor :number_of_codes

def self.register_subscription_code(submitted_code)
    matched_code = find_by(code: submitted_code, used: false)
    matched_code.update(used: true, date_used: DateTime.now)
    return matched_code.id
  end 
end
一些意见:

您将在每次保存时调用
:register\u subscription
,无论是创建还是更新。 尝试:

此外,如果曾经
:register\u subscription\u code
找不到代码,它将抛出
未定义方法更新
错误。尝试:

def self.register_subscription_code(submitted_code)
  matched_code = find_by(code: submitted_code, used: false)
  return nil unless matched_code
  matched_code.update(used: true, date_used: DateTime.now)
  matched_code.id # returns are implied at the ends of methods
end 
此方法将返回nil,错误将附加到订阅

最后一点,它是一个次要的点,但是在Rails中
nil
是错误的,因此如果注册了,那么就更容易理解为

最后一点,您已经在
submitted\u code
上进行了验证,因此无需在
:register\u subscription
中对其进行预验证。它只需要如下所示:

def register_subscription
  self.subscription_code_id = SubscriptionCode.register_subscription_code(self.submitted_code)
end

好的,最后一点,您不需要在
submitted\u code
上进行验证,这是一个
attr\u访问器。验证用于保持数据库中数据的一致性,而不是虚拟属性。

能否从SubscriptionController添加
创建
操作?我会添加一些日志消息,以了解哪些代码被多次命中。我应该发送哪些属性到日志以供显示?没关系,只是一些字符串,告诉你在应用程序代码正在运行。也就是说,
Rails.logger.debug“启动订阅注册”
就在
register\u Subscription
方法的内部。SystemStackError是由register\u expiration\u date方法引起的,该方法已在回调中保存。谢谢,但我得到一个SystemStackError:堆栈级别太深。当我查看日志时,它会反复更新订阅。为什么现在调用是递归的?
def self.register_subscription_code(submitted_code)
  matched_code = find_by(code: submitted_code, used: false)
  return nil unless matched_code
  matched_code.update(used: true, date_used: DateTime.now)
  matched_code.id # returns are implied at the ends of methods
end 
def register_subscription
  self.subscription_code_id = SubscriptionCode.register_subscription_code(self.submitted_code)
end