繁体   English   中英

Rails单表继承(STI):对不同的模型使用相同的视图会在“ new”操作中使form_for出现问题

[英]Rails Single Table Inheritance (STI): Use the same views for different models makes problems with form_for in 'new' action

我有一个Boilerplate模型,其中有两个降序模型:

  • BoilerplateOriginal
  • BoilerplateCopy

虽然BoilerplateOriginal s是管理员创建的模板,但BoilerplateCopy s是原始BoilerplateCopy的副本,每个人都可以自由编辑,并且它们还具有更多关联的对象(例如, BoilerplateCopy belongs_to: BoilerplateOriginalBoilerplateCopy belongs_to: ProjectBoilerplateCopy has_many: FindingsBoilerplateOriginal都没有)。

因此,我认为,维护两个具有相同基本功能的不同模型类是有意义的。

因为它们看起来也完全一样,所以我想对它们使用相同的视图。 但是在后台,它们的处理方式有所不同,因此我也有两个从基本控制器继承的不同控制器。

除了form_for boilerplate, as: resource_instance_name一切似乎都可以正常工作form_for boilerplate, as: resource_instance_name引发了一个undefined method oilerplates_path'异常, but only when called asaction, not when called as , but only when called as action, not when called as edit`操作时则没有。

到目前为止,这是我为使其正常工作所做的事情(其他所有事情似乎都可以正常工作):

# config/routes.rb
resources :boilerplate_originals

# app/models/boilerplate.rb
class Boilerplate < ActiveRecord::Base
  def to_partial_path
    'boilerplates/boilerplate'
  end
end

# app/models/boilerplate_original.rb
class BoilerplateOriginal < Boilerplate
end

# app/controllers/boilerplates_controller.rb
class BoilerplatesController < InheritedResources::Base
  load_and_authorize_resource

  private

  def boilerplate_params
    params.require(:boilerplate).permit(:title)
  end
end

# app/controllers/boilerplate_originals_controller.rb
class BoilerplateOriginalsController < BoilerplatesController
  defaults instance_name: 'boilerplate'
end

# app/views/boilerplates/_form.html.slim
= form_for boilerplate, as: resource_instance_name
  # ...

正如所指出的那样, new/create可以完美地工作,但是edit不能。 顺便说一下,我正在使用InheritedResources

Rails正确无误,您做错了一点

问题是:

resources :boilerplate_originals

只会生成特别是oilerplate_originals的路线。 使用rails的form_helpers时,rails会根据models类(在本例中为“ boilerplate_copy”)查找路线。 这意味着它正在寻找edit_boilerplate_copy_path(它不是由rails生成的)

您说过BoilerplateCopy和BoilerplateOriginal看起来几乎一样(我想您只是复制了一个模型,可以为您完成这些工作了……)

如果你去正确的性传播感染,它“应该”是

class Boilerplate; end
class BoilerplateCopy < Boilerplate; end
class BoilerplateOriginal < Boilerplate; end

为此,您只需要一条样板路线

resources :boilerplate

当然还有boilerplate_controller

一切都作为样板处理,并且form_helper将查找new_boilerplate_path ,无论存在副本还是原始副本,该new_boilerplate_path都存在。

我发现了问题。

# app/controllers/boilerplate_originals_controller.rb
class BoilerplateOriginalsController < BoilerplatesController
  defaults instance_name: 'boilerplate' # This is wrong!
  defaults instance_name: 'boilerplate', resource_class: BoilerplateOriginal # This is right!
end

现在,将BoilerplateOriginal对象而不是Boilerplate对象传递给new动作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM