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