Rails 5 次升级破坏了延迟任务
Rails 5 upgrade broke delayed tasks
我将我的 Rails 应用程序从 Rails 4.2
升级到 Rails 5.0
,现在我的许多 delayed jobs
是在升级前创建的,现在它们都坏了。我收到以下错误:
undefined method 'game_completion_feedback' for ConfirmationMailer:Class
即使我在 ConfirmationMailer
class 中定义了方法,但 class 或升级时调用它的地方没有任何改变。
在执行 YAML.load_dj
时出现以下错误:
ArgumentError: undefined class/module ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
from <path>/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/psych/class_loader.rb:53:in `path2class'
Caused by NameError: uninitialized constant
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
from <path>/.rvm/gems/ruby-2.2.5/gems/activesupport-5.0.7.1/lib/active_support/inflector/methods.rb:283:in `const_get'
看起来它坏了,因为在 Rails 4.2 到 Rails 5.0 升级期间发生了一些变化。
我在网上发现 运行 Rails.cache.clear
可以帮助解决这个问题,但是我在 production
环境中的 tmp
文件夹是空的,所以 运行 Rails.cache.clear
只是抛出一个错误:
No such file or directory @ dir_initialize - /var/app/current/tmp/cache/
有什么方法可以让这些旧的延迟作业在 Rails 5.0
中仍然有效,还是我只需要单独重新创建所有这些作业?
我的ConfirmationMailer
class:
class ConfirmationMailer < ApplicationMailer
def game_completion_feedback(user, date, feedback)
@user = user
@date = format_time(date.to_time)
@feedback = feedback
mail(to: user.email, subject: 'Game Completed')
end
end
我称该函数为:
def send_feedback_to_client
ConfirmationMailer.delay.game_completion_feedback(user, date, feedback)
end
在我调用 Struct
的其他情况下也会出现这种情况,例如:
class RemindersForGame < Struct.new(:gamer_email, :leader_email, :start)
def perform
ConfirmationMailer.game_reminder_email_gamer(gamer_email, leader_email, start).deliver_now
ConfirmationMailer.game_reminder_email_leader(gamer_email, leader_email, start).deliver_now
end
end
我称这个 struct
为:
def create_reminder_email(start)
reminders = Delayed::Job.enqueue RemindersForGame.new(client.user, coach, start),
run_at: start - 2.day,
queue: 'game_reminder'
self.reminders_job_id = reminders.id
结束
game_reminder_email_gamer
和 game_reminder_email_leader
的定义方式与 class 中的其他方法完全相同,我没有更改任何与它的调用方式相关的内容。
对于版本 < Rails 4.2:ConfirmationMailer.delay.game_completion_feedback(user, date, feedback)
对于版本 > Rails 4.2:ConfirmationMailer.game_completion_feedback(user, date, feedback).deliver_later
请尝试使用它,如果它能解决问题,请告诉我们。
此外,当将变量传递给您的 Mailer class 时,使用 with()
方法将创建实例变量供您在 Mailer 实例中使用。例如:
ConfirmationMailer.with(u: user, d: date, f: feedback).game_completion_feedback.deliver_later
然后将创建 @u, @d, @f
作为实例变量以在您的 Mailer 实例中使用。
我不是建议您将变量命名为单个字符 :) 但表明您不需要位置参数。
ArgumentError: undefined class/module ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
是由 Rails 5 中的变化引起的,因此 ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
和 ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float
不再存在。您可以使用以下迁移来解决此问题:
class UpdatePostgresDataTypeInDj < ActiveRecord::Migration[5.1]
REPLACEMENTS = {
'ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer': 'ruby/object:ActiveModel::Type::Integer',
'ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float': 'ruby/object:ActiveModel::Type::Float',
}
def up
REPLACEMENTS.each do |old, new|
Delayed::Job.where("handler LIKE ?", "%#{old}%")
.update_all("handler = replace(handler, '#{old}', '#{new}')")
end
end
def down
REPLACEMENTS.each do |old, new|
Delayed::Job.where("handler LIKE ?", "%#{new}%")
.update_all("handler = replace(handler, '#{new}', '#{old}')")
end
end
end
我将我的 Rails 应用程序从 Rails 4.2
升级到 Rails 5.0
,现在我的许多 delayed jobs
是在升级前创建的,现在它们都坏了。我收到以下错误:
undefined method 'game_completion_feedback' for ConfirmationMailer:Class
即使我在 ConfirmationMailer
class 中定义了方法,但 class 或升级时调用它的地方没有任何改变。
在执行 YAML.load_dj
时出现以下错误:
ArgumentError: undefined class/module ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
from <path>/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/psych/class_loader.rb:53:in `path2class'
Caused by NameError: uninitialized constant
ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
from <path>/.rvm/gems/ruby-2.2.5/gems/activesupport-5.0.7.1/lib/active_support/inflector/methods.rb:283:in `const_get'
看起来它坏了,因为在 Rails 4.2 到 Rails 5.0 升级期间发生了一些变化。
我在网上发现 运行 Rails.cache.clear
可以帮助解决这个问题,但是我在 production
环境中的 tmp
文件夹是空的,所以 运行 Rails.cache.clear
只是抛出一个错误:
No such file or directory @ dir_initialize - /var/app/current/tmp/cache/
有什么方法可以让这些旧的延迟作业在 Rails 5.0
中仍然有效,还是我只需要单独重新创建所有这些作业?
我的ConfirmationMailer
class:
class ConfirmationMailer < ApplicationMailer
def game_completion_feedback(user, date, feedback)
@user = user
@date = format_time(date.to_time)
@feedback = feedback
mail(to: user.email, subject: 'Game Completed')
end
end
我称该函数为:
def send_feedback_to_client
ConfirmationMailer.delay.game_completion_feedback(user, date, feedback)
end
在我调用 Struct
的其他情况下也会出现这种情况,例如:
class RemindersForGame < Struct.new(:gamer_email, :leader_email, :start)
def perform
ConfirmationMailer.game_reminder_email_gamer(gamer_email, leader_email, start).deliver_now
ConfirmationMailer.game_reminder_email_leader(gamer_email, leader_email, start).deliver_now
end
end
我称这个 struct
为:
def create_reminder_email(start)
reminders = Delayed::Job.enqueue RemindersForGame.new(client.user, coach, start),
run_at: start - 2.day,
queue: 'game_reminder'
self.reminders_job_id = reminders.id
结束
game_reminder_email_gamer
和 game_reminder_email_leader
的定义方式与 class 中的其他方法完全相同,我没有更改任何与它的调用方式相关的内容。
对于版本 < Rails 4.2:ConfirmationMailer.delay.game_completion_feedback(user, date, feedback)
对于版本 > Rails 4.2:ConfirmationMailer.game_completion_feedback(user, date, feedback).deliver_later
请尝试使用它,如果它能解决问题,请告诉我们。
此外,当将变量传递给您的 Mailer class 时,使用 with()
方法将创建实例变量供您在 Mailer 实例中使用。例如:
ConfirmationMailer.with(u: user, d: date, f: feedback).game_completion_feedback.deliver_later
然后将创建 @u, @d, @f
作为实例变量以在您的 Mailer 实例中使用。
我不是建议您将变量命名为单个字符 :) 但表明您不需要位置参数。
ArgumentError: undefined class/module ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
是由 Rails 5 中的变化引起的,因此 ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer
和 ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float
不再存在。您可以使用以下迁移来解决此问题:
class UpdatePostgresDataTypeInDj < ActiveRecord::Migration[5.1]
REPLACEMENTS = {
'ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Integer': 'ruby/object:ActiveModel::Type::Integer',
'ruby/object:ActiveRecord::ConnectionAdapters::PostgreSQL::OID::Float': 'ruby/object:ActiveModel::Type::Float',
}
def up
REPLACEMENTS.each do |old, new|
Delayed::Job.where("handler LIKE ?", "%#{old}%")
.update_all("handler = replace(handler, '#{old}', '#{new}')")
end
end
def down
REPLACEMENTS.each do |old, new|
Delayed::Job.where("handler LIKE ?", "%#{new}%")
.update_all("handler = replace(handler, '#{new}', '#{old}')")
end
end
end