现在这很有道理了。我没有遇到问题,是因为即使在修改 Discourse 核心代码时,我也会重启服务器,而不是重新加载代码。
我最近做了一件事:虽然我还远不像在座许多 Rails 应用专家那样精通,但我规划了哪些配置变量需要在不重启 Rails 的情况下重新加载,并将相关代码移到了 ApplicationController 中。
我相信肯定有更好的做法,但由于这个特定的 Rails 实现是一个后台办公应用,性能并非问题:
class ApplicationController < ActionController::Base
before_action :set_site_settings
private
def set_site_settings
@use_custom_date_format = Sitesetting.where(name: "custom_date_format").pluck(:value).last
end
end
当我找到更好的实现方式时,我会非常高兴!
不过,将这部分逻辑从 Rails 初始化器中移出意味着用户可以轻松更改此站点设置,因为它现在存储在数据库中,并可通过基本的 Rails MVC CRUD 脚手架进行操作。
由于 Rails 中的 SQL 缓存无法在动作作用域之外生效,总有一天我需要学习如何将此逻辑移至缓存中,并确保在 Rails 控制器处理动作时(例如在站点设置控制器中保存新值等)缓存能够正确清除。
总之,这个面向客户的 Rails 应用(仅限后台办公)并不需要高性能支持,因此在 ApplicationController 中添加该查询完全可以接受,也避免了在项目中每个需要使用该站点设置的控制器里重复编写这段代码。
嘿 @fzngagan,我当然算不上是"Ruby 专家”,在 Rails 方面的经验也比大多数 Discourse 插件开发者少得多;但话说回来:如果你需要在不重启应用(无论是在生产环境还是开发环境)的情况下重载插件中的文件,未来或许可以尝试像下面这样的方法:
after_initialize do
# 将以下内容更改为你选择的控制器
# 或者,如果需要,也可以使用 Application 控制器
ApplicationController.class_eval do
before_action :do_my_stuff
def do_my_stuff
load File.open(FAIZAANS_FAV_FILE)
end
end
end
这将按预期重载文件。
我目前在一个插件中就是这样使用的,效果符合预期:
after_initialize do
Admin::AdminController.class_eval do
before_action :do_neo_plugin_info
def do_neo_plugin_info
load File.open(PLUGIN_LOGIC)
end
end
end
我目前在一个间歇性开发的插件中使用这段代码,它用于显示容器名称(从 ENV["DATA_NAME"] 解析)以及通过系统代码使用 df 和 grep 解析出的磁盘空间。
在我们的管理视图中:
如前所述,我绝非 Ruby 专家;但这个方法对我很有效。
我查看了 instance.rb 中的插件代码,在尝试了不同的方法并经历了一些错误后,我决定采用上面的 class_eval 代码。这可能不是最佳实践,但它确实对我有效。
例如,如果在删除大量 Discourse 备份后刷新页面,磁盘空间指示器会按预期发生变化。
