在rails中处理STI子类的路由的最佳实践

我的Rails视图和控制器充斥着redirect_tolink_toform_for方法调用。 有时link_toredirect_to在它们链接的路径中是明确的(例如link_to 'New Person', new_person_path ),但路径隐含多次(例如link_to 'Show', person )。

我在模型中添加了一些单表继承(STI)(称为Employee < Person ),并且所有这些方法都会为子类的实例(称为Employee )分解; 当rails执行link_to @personundefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>undefined method employee_path' for #<#<Class:0x000001022bcd40>:0x0000010226d038>发生错误。 Rails正在寻找由该对象的类名称定义的路由,该名称是员工。 这些员工路线未定义,并且没有员工控制器,因此这些操作也未定义。

这个问题之前曾被问过:

  • 在StackOverflow中,答案是在整个代码库中编辑link_to等的每个实例,并明确声明路径
  • 在StackOverflow上,两个人建议使用routes.rb将子类资源映射到父类( map.resources :employees, :controller => 'people' )。 在同样的SO问题中,最佳答案建议使用.becomes对代码库中的每个实例对象进行类型转换
  • 在StackOverflow上的另一个例子中,最重要的答案就是Do Repeat Yourself阵营,并建议为每个子类创建重复的脚手架。
  • 在这里,同样的问题再次出现在最上面的答案似乎是错误的(Rails magic Just Works!)
  • 在网络上的其他地方,我发现F2Andy建议在代码中的任何地方编辑路径。
  • 在逻辑现实设计的单表继承和RESTful路由的博客文章中,建议将子类的资源映射到超类控制器,如上面的答案2所示。
  • 亚历克斯·赖斯纳在Rails的后单表继承中,他主张对映射子类在父类的资源routes.rb ,因为只有抓住路由从破损link_toredirect_to ,而不是从form_for 。 所以他建议在父类中添加一个方法来让子类对他们的类进行说谎。 听起来不错,但他的方法给了我错误undefined local variable or method `child' for #
  • 因此,看起来最优雅,最具共识的答案(但并不是那么优雅,也没有那么多共识),就是将这些资源添加到您的routes.rb 。 除了这不适用于form_for 。 我需要一些清晰! 为了提炼上述选择,我的选择是

  • 将子类的资源映射到routes.rb类的控制器(并希望我不需要在任何子类上调用form_for)
  • 覆盖导轨的内部方法以使这些类彼此相互依赖
  • 编辑代码中隐藏或显式调用对象操作路径的每个实例,或者更改路径或对对象进行类型转换。
  • 所有这些相互矛盾的答案,我需要一个裁决。 在我看来,似乎没有好的答案。 这是轨道设计失败吗? 如果是这样,它是一个可能得到修复的错误? 或者如果没有,那么我希望有人能够让我直接了解这一点,通过每个选项的利弊(或解释为什么这不是一种选择),哪一个是正确的答案,以及为什么。 或者有没有一个正确的答案,我没有在网上找到?


    这是我能够以最小的副作用提出的最简单的解决方案。

    class Person < Contact
      def self.model_name
        Contact.model_name
      end
    end
    

    现在, url_for @person将按照预期映射到contact_path

    工作原理: URL助手依靠YourModel.model_name来反思模型并生成(在许多事情中)单数/复数路由密钥。 这里Person基本上是说我就像Contact老兄,问他。


    我有同样的问题。 使用STI后, form_for方法发布到错误的子网址。

    NoMethodError (undefined method `building_url' for
    

    我最终为子类添加了额外的路由并将它们指向相同的控制器

     resources :structures
     resources :buildings, :controller => 'structures'
     resources :bridges, :controller => 'structures'
    

    另外:

    <% form_for(@structure, :as => :structure) do |f| %>
    

    在这种情况下,结构实际上是一个建筑物(儿童班)

    在使用form_for提交后,它似乎适用于我。


    我建议你看看:https://stackoverflow.com/a/605172/445908,使用这种方法可以让你使用“form_for”。

    ActiveRecord::Base#becomes
    
    链接地址: http://www.djcxy.com/p/63551.html

    上一篇: Best practices to handle routes for STI subclasses in rails

    下一篇: Fully custom validation error message with Rails