【问题标题】:Value gets set even though before_save sets it to nil即使 before_save 将其设置为 nil,值也会被设置
【发布时间】:2015-07-03 00:41:37
【问题描述】:

我正在使用 aasm_state gem 和 sidekiq。这是customer.rb对于aasm_state的定义的样子:

  aasm do
    state :closed, initial: true
    state :open
    state :claimed

    event :open do
      transitions from: :closed, to: :open
    end

    event :claim do
      transitions from: [:open, :closed], to: :claimed
    end

    event :close do
      transitions from: [:open, :claimed], to: :closed
      before do
        self.user_id = nil
      end
    end
  end

然后我在customer.rb中也有:

  def properly_close
    if closed? && user_id
      Rails.logger.info "Bad customer state with customer_id: #{id} at #{Time.now} and the last message was at #{messages.last.created_at}. Aasm_state_was: #{aasm_state_was}"
      self.user_id = nil
    end
  end

只要 aasm_state == '已关闭',客户上就不应该有 user_id。但是,它仍然经常发生。我认为这与sidekiq 并行工作有关,但我不确定。即使我有两种方法来确保 user_id = nil(在 before do 和 proper_close 中),它仍然最终被设置为 aasm_state == 'closed' && user_id

这怎么可能?我如何弄清楚它是如何发生的?

【问题讨论】:

  • 表中有 lock_version 列吗?尝试通过添加此列将其添加到打开内置乐观锁定机制。至少它可能有助于找出对该表的更多并发访问。
  • 我会试试看的。但是,只要考虑一下 activerecord/sidekiq 的工作原理,如果每个作业的单个值永远不会是 aasm_state = closed && user_id not nil,我很难理解并发性是如何成为问题的。
  • 你是用update_attribute直接设置状态吗? update_attribute 将绕过验证和回调。

标签: ruby-on-rails activerecord sidekiq


【解决方案1】:

在这两种情况下,您都需要save 更新,即:

self.user_id = nil
self.save

或者更简洁(并且跳过回调):

self.update_attribute :user_id, nil

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 2011-01-21
    • 2018-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多