如何在 Rails 中找到方法来自的模块/类?
Posted
技术标签:
【中文标题】如何在 Rails 中找到方法来自的模块/类?【英文标题】:How to find the module/class where a method comes from in Rails? 【发布时间】:2022-01-20 23:08:15 【问题描述】:使用 Rails,我最初是在寻找一种在模型中使用资源路径辅助方法(例如 users_path
)的方法,而 this 给了我答案:我可以使用 Rails.application.routes.url_helpers.users_path
。
很好,但总的来说,特别是在 Rails 中,如何找到一个方法来自哪个模块/类?阅读源代码或一些官方文档是找到它的唯一方法吗?是不是可以例如直接在调试控制台中签入从users_path
获取Rails.application.routes.url_helpers
?
【问题讨论】:
Ruby 中没有“命名空间”之类的东西。你的问题不清楚。 “命名空间”是什么意思? “来自”是什么意思?您是在询问定义该方法的模块吗?还是定义它的脚本位置? 已编辑。现在没有命名空间了。 澄清后,您的问题与***.com/q/69149392/2988、***.com/a/9003022/2988、***.com/a/7247156/2988 和许多其他问题重复。 在我看来,您对定义方法的位置不感兴趣,而是对可以调用该方法的对象感兴趣。在您的示例中,users_path
是由元编程定义的,因此您根本不会在代码中找到具有该方法名称的方法定义。但是可以在控制器和视图的上下文中在Rails.application.routes.url_helpers
上调用该方法。
@spickermann 另外可能有多个这样的对象。您必须确定与当前自我“最接近”的那个。
【参考方案1】:
我认为您正在寻找的内容类似于此问题How to find where a method is defined at runtime?。
简而言之,在 Ruby 2+ 中,以下(其中之一)将返回文件名和行号的 2 元素数组:
method(:users_path).source_location
my_object.method(:my_method).source_location
# => ["/My/Ruby/Code/some-module.rb", 123]
然后您可以计算出该方法的模块或类名称。
[在编辑中添加]
要获取模块名称,您可以改用method(:users_path).owner
:参见Answer1 和answer2。
然而,Rails 使用了大量的元编程和动态赋值。问题中的users_path
之类的url-helper 就是其中之一。
引用@spickermann 对该问题的评论
users_path
是由元编程定义的,因此您在代码中根本找不到具有该方法名称的方法定义。
引用@Stefan 对该问题的评论
可能有多个这样的对象。你必须找出与当前自我“最接近”的那个。
具体来说,url_helpers
在 Rails 6.0 的 actionpack-6.*/lib/action_dispatch/routing/route_set.rb
中定义,您会看到 generate_url_helpers
方法负责(动态)生成它。这就是为什么method(:users_path).owner
返回类似#<Module:0x0000000117346e18>
的东西的原因,这并没有真正的帮助。甚至method(:users_path).source_location
也只是指向了
mod.define_method(name) do |*args|
(或类似的东西,取决于 Rails 版本),表示对象是动态生成的。
因此,我怀疑是否有任何简单的方法do-all 从给定的辅助函数(如users_path
)派生一个 Rails 对象(类/模块),例如Rails.application.routes.url_helpers
.但是使用owner
和source_location
等方法的组合进行分析将非常有助于查明它,并且在某些情况下可能会为您提供您正在寻找的答案。
我注意到,就这个具体案例而言,actionpack-6*.*/lib/abstract_controller/url_for.rb
中写的错误消息会有所帮助——引用:
为了使用#url_for,您必须明确包含路由助手。 例如,
include Rails.application.routes.url_helpers
。
【讨论】:
总比没有线索要好,但我还应该真正阅读代码吗? @akai 我已经编辑了我的答案,以便将我的答案版本添加到您的评论中。以上是关于如何在 Rails 中找到方法来自的模块/类?的主要内容,如果未能解决你的问题,请参考以下文章
如何检查定义的方法?来自在类中使用的模块,其中包含模块后定义的方法
如何在 Rails 中正确使用控制器辅助模块,以及如何连接这些辅助模块?