我的 Rails 视图和控制器散布着redirect_to
, link_to
, and form_for
方法调用。有时link_to
and redirect_to
它们链接的路径是明确的(例如link_to 'New Person', new_person_path
),但很多时候路径是隐式的(例如link_to 'Show', person
).
我向我的模型添加了一些单表继承 (STI)(例如Employee < Person
),并且所有这些方法都会因子类的实例而中断(例如Employee
);当 Rails 执行时link_to @person
,它的错误是undefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>
。 Rails 正在寻找由对象的类名(employee)定义的路由。这些员工路线未定义,并且没有员工控制器,因此操作也未定义。
这个问题之前已经被问过:
- At 堆栈溢出 https://stackoverflow.com/questions/1773367/link-to-issue-with-inherited-active-record-class,答案是编辑整个代码库中 link_to 等的每个实例,并明确说明路径
- On 堆栈溢出 https://stackoverflow.com/questions/702728/get-route-for-base-class-of-sti-class-in-rails再次,有两个人建议使用
routes.rb
将子类资源映射到父类(map.resources :employees, :controller => 'people'
)。同一个 SO 问题中的最佳答案建议使用以下命令对代码库中的每个实例对象进行类型转换.becomes
- 还有一个在堆栈溢出 https://stackoverflow.com/questions/4432858/broken-rails-routes-after-implementing-single-table-inheritance,最重要的答案是“重复自己”阵营,并建议为每个子类创建重复的脚手架。
-
Here's https://stackoverflow.com/questions/943300/single-table-inheritance-routing同样的问题在 SO 再次出现,其中最重要的答案似乎是错误的(Rails magic Just Works!)
- 在网络的其他地方,我发现这篇博文 http://strugglingwithruby.blogspot.com/2008/10/single-table-inheritance.html其中 F2Andy 建议在代码中的任意位置进行编辑。
- 在博客文章中单表继承和 RESTful 路由 http://blog.lrdesign.com/2009/03/single-table-inheritance-and-restful-routes/在逻辑现实设计中,建议将子类的资源映射到超类控制器,如上面的答案 2 所示。
- 亚历克斯·雷斯纳 有一个帖子Rails 中的单表继承 http://www.alexreisner.com/code/single-table-inheritance-in-rails,其中他主张反对将子类的资源映射到父类
routes.rb
,因为这只捕获路由中断link_to
and redirect_to
,但不是来自form_for
。因此他建议向父类添加一个方法,让子类对它们的类撒谎。听起来不错,但他的方法给了我错误undefined local variable or method `child' for #
.
所以看起来最优雅、最有共识的答案(但也不是全部)that优雅,也不that达成共识),是将资源添加到您的routes.rb
。但这不适用于form_for
。我需要一些澄清!为了提炼上面的选择,我的选择是
- 将子类的资源映射到超类的控制器
routes.rb
(并希望我不需要在任何子类上调用 form_for )
- 重写 Rails 内部方法以使类相互欺骗
- 编辑代码中隐式或显式调用对象操作路径的每个实例,更改路径或对对象进行类型转换。
面对所有这些相互矛盾的答案,我需要做出裁决。在我看来,似乎没有好的答案。这是 Rails 设计的失败吗?如果是这样,这是一个可以修复的错误吗?或者如果没有,那么我希望有人能直接告诉我这个问题,引导我了解每个选项的优点和缺点(或解释为什么这不是一个选项),以及哪个是正确的答案,以及为什么。或者我在网上找不到正确的答案?
这是我能想到的最简单的解决方案,副作用最小。
class Person < Contact
def self.model_name
Contact.model_name
end
end
Now url_for @person
将映射到contact_path
正如预期的那样。
怎么运行的:URL 助手依赖YourModel.model_name
反思模型并生成(其中包括)单数/复数路径键。这里Person
基本上是在说我就像Contact
老兄,问他吧.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)