Rails - 点击事件 - 如何处理 2 Ruby 方法之间的竞争条件?

Rails - on click event - how to deal with race condition between 2 Ruby methods?

在我看来,我有一个 link_to 元素 "Start Quiz!",它调用控制器方法(方法 A)来设置变量 "Phase" 并将用户重定向到新的静态页面。在我的 CoffeeScript 中,我有一个事件侦听器侦听对此 link_to 元素的点击。侦听器在后端调用不同的方法(方法 B),该方法使用 "Phase" 变量来执行某事。

问题:有时方法 B 会在控制器方法 A 更新之前尝试使用 "Phase" 变量!有没有人建议确保 "Phase" 变量在用于其他任何事情之前得到更新的最佳方法是什么?

我是 Rails 初学者,非常感谢任何指点。 :)


编辑: "Phase" 是我用来跟踪当前测验问题的变量。它不依赖于任何输入,但每当呈现新页面(由单击按钮触发)时它都需要递增。


编辑2: 我现在试图通过向我的控制器引入一个实例变量标志 "is_changed" 并让方法 B 休眠直到标志设置为 true 来解决这个问题:

#method B:
def send_answers
   until controller.index_changed?
     sleep(0.5)
   end
   ...
   do sth.
end

#method A (in controller):
def initialize
   @index_changed = false
end

def index_changed?
   @index_changed
end

def set_index_changed!
   @index_changed = false
end

def switch_to_next_question
   ...
   self.phase += 1
   if self.save
      Thread.new do
         @index_changed = true
         ActiveRecord::Base.connection.close
      end
   else
      ...
   end
end

它不起作用。方法A卡在睡眠中。我该如何解决?这是正确的方法吗?

是不是我的@index_changed变量的作用域有问题?我正在尝试创建一个可从 class 中的多个方法访问的实例变量,但对于此 class.

的每个实例都是单独的

好的,我通过找到一种顺序调用这 2 个方法的方法解决了这个问题。我最终完全消除了点击侦听器并直接调用 ActionCable 后端方法,这可以通过将其转换为 class 方法来实现:

class QuizDataChannel < ApplicationCable::Channel
  #method B:
  def self.send_answers #self. makes it a class method
    #...
    #do something with phase
  end
end

在我的控制器中:

#method A:
def switch_to_next_question
   #...
   self.phase += 1
   if self.save
      QuizDataChannel.send_answers
   else
      #...
   end
end

正如您最后看到的那样,我摆脱了所有这些:sleep、新线程和 index_changed 标志。