使用 Sequel::Model.plugin 时间戳和触摸时出现 NoExistingObject 异常

NoExistingObject exception when using Sequel::Model.plugin timestamps and touch

作为项目的一部分,我创建了一个 Session 模型来存储它首次创建和更新的日期(使用 Sequel 提供的 timestamps 插件)。这是为了促进服务器端处理会话超时。 updated_at 列可以使用 Sequel 的 touch 插件更新,它提供了等效的方法。

但是,当我尝试使用它时,收到以下错误

Sequel::NoExistingObject: Attempt to update object did not result in a single row modification (SQL: UPDATE sessions SET updated_at = '2016-07-01 12:17:06.373469' WHERE (id = 14))
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:2018:in _update'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:2011:in_update_columns'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1965:in block (2 levels) in _save'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1146:inaround_update'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1949:in block in _save'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1146:inaround_save'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1935:in _save'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:1587:inblock (2 levels) in save'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:2089:in block in checked_transaction'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/database/transactions.rb:163:in_transaction'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/database/transactions.rb:138:in block in transaction'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/database/connecting.rb:251:inblock in synchronize'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/connection_pool/threaded.rb:105:in hold'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/database/connecting.rb:251:insynchronize'
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/database/transactions.rb:104:in transaction'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/sequel-4.35.0/lib/sequel/model/base.rb:2089:inchecked_transaction'
... 7 levels...
from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/console.rb:9:in start'<br> from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:68:inconsole' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands/commands_tasks.rb:39:in run_command!' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/railties-4.2.6/lib/rails/commands.rb:17:in' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:in require' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:inblock in require' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:in load_dependency' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:274:inrequire' from /Users/[FILTERED USERNAME]/Sync/RubymineProjects/[FILTERED PROJECT NAME]/bin/rails:9:in <top (required)>' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:inload' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in block in load' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:240:inload_dependency' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activesupport-4.2.6/lib/active_support/dependencies.rb:268:in load' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:inrequire' from /Users/[FILTERED USERNAME]/.rbenv/versions/2.3.1/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in require' from -e:1:in'

我已经尝试使用 Sequel::Model.updateSequel::Model.update_all 方法,但无济于事(收到相同的错误)。

有趣的是,我能够 运行 通过命令行生成上面的 SQL 查询,同时使用 SQLite 和 MySQL。

==== app/models/session.rb ====

class Session < Sequel::Model
  plugin :validation_helpers
  plugin :timestamps
  plugin :touch

  def before_update
    self.touch
  end

  def before_save
    Session.where(user_id: self.user_id).delete
  end

  def self.sweep(time = 2.hours)
    time = time.split.inject { |count, unit| count.to_i.send(unit) } if time.is_a?(String)
    Session.where("updated_at < '#{time.ago.to_s(:db)}' OR created_at < '#{1.day.ago.to_s(:db)}'").delete
  end

  def validates
    validates_presence [:user_id]
  end
end

预先感谢您提供的任何帮助。

def before_save
  Session.where(user_id: self.user_id).delete
end

这将在保存会话之前删除会话 table 中具有相同 user_id 的所有行,包括当前行(如果更新而不是创建)。如果你只想允许一个会话,你应该切换到使用 before_create。另外,不要忘记在钩子中调用 super