Rails 中类变量的线程安全 - 这可行吗?

发布于 2025-01-01 02:14:39 字数 1245 浏览 1 评论 0原文

我正在多租户 (SaaS) Rails 应用程序中使用 Ruby Money gem,并且正在寻找将 Money.default_currency 设置为每个请求的帐户首选项的好方法。我的应用程序中有几个使用 Money 类的货币相关模型。

我在开发中一切正常,但我只是在寻找一些关于该解决方案是否对生产产生影响的反馈。

这是我在 ApplicationController 中所做的操作(为简洁起见,删除了不相关的代码):

class ApplicationController < ActionController::Base
  before_filter :set_currency

  private

  def set_currency
    Money.default_currency = Money::Currency.new(current_account.present? && current_account.currency.present? ?
                                                 current_account.currency : 'USD')
  end
end

因此上面的代码会将 default_currency 类变量设置为当前帐户的首选项,或者如果没有,则默认返回“USD”一。

顺便说一句,这里是 Money 类中的相关 default_currency 代码:

class Money

  # Class Methods
  class << self

    # The default currency, which is used when +Money.new+ is called without an
    # explicit currency argument. The default value is Currency.new("USD"). The
    # value must be a valid +Money::Currency+ instance.
    #
    # @return [Money::Currency]
    attr_accessor :default_currency

  end
end

那么,这在多用户设置中会按预期工作吗?我还需要做什么吗?

I'm using the Ruby Money gem in a multi-tenant (SaaS) Rails app, and am looking for a good way to make the Money.default_currency be set to an Account's preference for each request. I have several currency-related models in the app that use the Money class.

I have everything working properly in development, but I'm just looking for some feedback on whether or not the solution with have repercussions in production.

Here's what I did in my ApplicationController (irrelevant code removed for brevity):

class ApplicationController < ActionController::Base
  before_filter :set_currency

  private

  def set_currency
    Money.default_currency = Money::Currency.new(current_account.present? && current_account.currency.present? ?
                                                 current_account.currency : 'USD')
  end
end

So the code above will set the default_currency class variable to the current account's preference, or default back to 'USD' if there isn't one.

By the way, here's the relevant default_currency code in the Money class:

class Money

  # Class Methods
  class << self

    # The default currency, which is used when +Money.new+ is called without an
    # explicit currency argument. The default value is Currency.new("USD"). The
    # value must be a valid +Money::Currency+ instance.
    #
    # @return [Money::Currency]
    attr_accessor :default_currency

  end
end

So, will this work as expected in a multi-user setting? Anything else I need to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

匿名。 2025-01-08 02:14:39

大多数 Rails 应用程序都不以多线程模式运行 - 给定实例一次仅处理一个请求(这是默认设置)。

如果您的应用处于多线程模式,这将是危险的 - Money.default_currency 可能会在请求中途被刚刚传入的新请求更改。如果您确实想让该线程安全,您可以可以使用 Thread.current 哈希来获得每个线程的 default_currency 值

Most rails apps don't run in multithreaded mode - a given instance is only ever handling one request at a time (this is the default).

If your app was in multithreaded mode this would be dangerous - Money.default_currency could get changed halfway through a request by the new request that has just come in. If you did want to make this thread safe, you could use the Thread.current hash to have per thread values of default_currency

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文