Rails Circular dependency 的问题

robot_zhang · 2015年08月17日 · 最后由 msg7086 回复于 2015年08月18日 · 4435 次阅读

大家有遇到过循环依赖的问题吗?

启动服务器之后(webrick 能顺利启动)后端会出现一行 warning

warning: toplevel constant Account referenced by Shop::Account

和 RuntimeError

RuntimeError - Circular dependency detected while autoloading constant Shop::Account::CustomersHelper:

分析下来 rails load Shop::Account::CustomersHelper 的时候会去加载 Shop::AccountShop::Account 中又重新加载了 CustomersHelper 导致的,但是我没有找到异常的代码,所以现在没有找到头绪,我想问大家如何能够看到 rails 的 class & module 的加载顺序和记录以便找到最终问题出现在那个地方?

跟踪错误的时候发现 rails load helpers 的时候居然 load shop model,才惊醒可能 shop model 已经占用了 Shop 常量,导致 load Shop::Account:CustomersHelper 的时候没找到而出发了,load_miss_const 方法,于是自然就会报错了。

解决方案是:

  1. 将 shop namespace 改成其他的
  2. 关闭 rails helpers 的 autoload
config.action_controller.include_all_helpers = false

3.将 helpers 中 shop 下面的子目录全部删除掉

不过总觉得不是很舒服,而且对于 rails 为什么要这么做也有疑问,迫于时间留在后面研究,或者大家说些经验?

应该就是你的 model class name 与顶层 namespace 冲突了。 所以结论就是不要把整个 App 命名成和某个 model 一样。

@msg7086 确实是这个问题,model 的 name 不但不能和整个 App 命名一样,还不能和 Helpers 的 namespace 一样。

#3 楼 @robot_zhang 其实道理也很简单。 因为他们都是常量。

@msg7086 应该有更改的解决方案,否则总是会比较别扭,比如将 Shop::Account 改成 Store::Account

#5 楼 @robot_zhang 搜索替换就行了。App 名出现的地方不多的。

@msg7086 不是和 App 命名冲突,是 model 和 controller 子目录冲突, 结构是这种:app/controllers/shop/account/customers_helper 就是说 shop 子目录和 model 的常量冲突

#7 楼 @robot_zhang 哦哦没注意,原来是 namespace 与 model 冲突。 话说这是应该用 namespace 的场景么?不是 nested resource? 如果是 namespace 的话的确只能改 namespace 名了。 比如 MyShop::Settings 这样。 Shop/X/Account/Y的话感觉应该用nested resource。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号