我的Rails视图和控制器上到处是redirect_to
,link_to
和form_for
方法调用。有时link_to
,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正在寻找由对象的类名(即员工)定义的路线。这些员工路线未定义,也没有员工控制者,因此也未定义操作。
之前已经问过这个问题:
- 在StackOverflow上,答案是编辑整个代码库中的每个link_to等实例,并明确声明路径
- 再次在StackOverflow上,两个人建议使用
routes.rb
来将子类资源映射到父类(map.resources :employees, :controller => 'people'
)。在同一SO问题中的最高答案建议使用以下方法对代码库中的每个实例对象进行类型转换.becomes
- 在StackOverflow上,另一个答案是,“做自己重复做”阵营中的方法,并建议为每个子类创建重复的脚手架。
- 在SO中,这又是同样的问题,其中最高答案似乎是错误的(Rails magic Just Works!)
- 在网络上的其他地方,我发现了此博客文章,F2Andy建议在代码中的所有路径中进行编辑。
- 在博客文章Logical Reality Design上的Single Table Inheritance和RESTful Routes上,建议将子类的资源映射到超类控制器,如上面的SO答案2所示。
- Alex Reisner在Rails中发表了“单表继承”一文,他主张不要将子类的资源映射到父类中
routes.rb
,因为这只会从link_to
和redirect_to
而不是从中捕获路由中断form_for
。因此,他建议改为在父类中添加一个方法,以使子类位于其类周围。听起来不错,但是他的方法给了我错误undefined local variable or method `child' for #
。
所以这似乎是最优雅,拥有最共识(但不是所有的答案是优雅的,也不是太大的共识),是资源添加到您的routes.rb
。除非这不适用于form_for
。我需要澄清!为了提炼以上选择,我的选择是
- 将子类的资源映射到超类的控制器中
routes.rb
(并希望我不需要在任何子类上调用form_for) - 重写rails内部方法以使类相互说谎
- 在代码中编辑每个实例,以隐式或显式调用对象操作的路径,从而更改路径或类型转换对象。
鉴于所有这些矛盾的答案,我需要裁决。在我看来,没有好的答案。这是滑轨设计的失败吗?如果是这样,它是否可以修复?如果不是这样,那么我希望有人可以让我直接理解这一点,带我逐步了解每种选择的优缺点(或解释为什么这不是一种选择),以及哪个是正确的答案以及为什么。还是我在网上找不到合适的答案?