Ruby on rails 路由到未保存父项的嵌套模型/表单

Ruby on rails 路由到未保存父项的嵌套模型/表单,ruby-on-rails,forms,routing,model,nested,Ruby On Rails,Forms,Routing,Model,Nested,对于属于父列表模型的模型计划,我有一个复杂的表单: class Listing < ActiveRecord::Base has_many :schedules, :dependent => :destroy accepts_nested_attributes_for :schedules, :allow_destroy => true, :reject_if => :all_blank ... end class Schedule < ActiveR

对于属于父列表模型的模型计划,我有一个复杂的表单:

class Listing < ActiveRecord::Base
  has_many :schedules, :dependent => :destroy
  accepts_nested_attributes_for :schedules, :allow_destroy => true, :reject_if => :all_blank
  ...
end

class Schedule < ActiveRecord::Base
  belongs_to :listing
  ...
end
这在编辑现有列表时效果很好,但用于构建复杂时间表表单的表单_在新列表中出现:

 => No route matches {:action=>"create", :controller=>"schedules")
在我的路线中,我有(Rails 3):

这当然很有意义,因为预期的路径是/listings/:listing_id/schedules/new,但我想知道是否有一种方法可以使用form_for builder为属于未保存父对象的嵌套模型生成表单/清单/新的/时间表/新的似乎很荒谬,但完美地总结了我所追求的

谢谢你的建议

编辑: 我应该补充一点,我正在Listings控制器的new和edit方法中构建新的日程实例,如下所示:

def new
  @listing = Listing.new
  @schedule = @listing.schedules.build
end

def edit
  @listing = Listing.find(params[:id])
  @schedule = @listing.schedules.build
end

默认情况下,您不能使用form_for在新父对象下执行嵌入对象,因为控制器无法返回新对象的子对象,因为您无法将子对象分配给没有id的对象。您必须设置自定义路由。不过,从概念上讲,这个限制是有意义的——您没有请求应用程序返回新对象的子对象,因为在创建对象之前您无法创建子对象,因此您可以调用非嵌入路由,只需为(@schedule)创建表单_。然后,只需将整个构建树作为一个对象返回,这样它就可以一起保存。您必须将其嵌入到最终的保存请求中,在此之前,没有嵌入对象。

发现另一个可能相关的奇怪事情;当我尝试使用url_为(:listing,@schedule)生成链接(在电子邮件视图模板中)时,我没有得到任何路由匹配{:action=>“destroy”,:controller=>“schedules”}。路由仍然如上所述,它应该提供一个“破坏”路由——但当然url_不应该担心“破坏”,应该只是一个“得不到”的东西,是的,这是有道理的。缺点是我必须有一个从根目录开始的时间表路由,尽管它们不应该直接访问,因为时间表总是属于列表。不过,我已经做出了改变,而且似乎奏效了。但是现在,当清单没有任何时间表时,我对清单的create方法有一个问题。我不得不这么做:除非@schedule@schedule=@listing.schedules.build——但这会导致插入一个空的时间表。您可以始终将新的时间表表单存储在javascript函数中,就在新的列表页面上,那么我想您根本不需要回拨,从而消除了混乱的路由。至于你的新问题,让我理解一下这里的逻辑——那么,一个清单需要有一个或多个时间表吗?生成行的目的是什么?schedule.build的目的是克服当表单在没有计划的情况下提交且未能通过验证时收到的错误消息。listings控制器似乎触发了create函数,并抱怨schedule是一个没有它的nil类。出于相同的原因,“新建”和“编辑”方法已具有schedule.build。一个列表可以有任意数量的计划,包括无计划。至于预构建表单解决方案,这当然有效。我曾经(出于绝望)将表单的一个平面HTML呈现粘贴到中,效果很好。但这种做法对我来说似乎完全偏离了轨道!我同意有一个更优雅的解决方案会很好,而且感觉“没有那么粗鲁”。我所做的是在schedules视图中使表单成为一个部分,然后在listings视图中从我的较大页面调用它——如果这有意义的话。这与您刚才说的没有什么不同,只是我提前检索了部分内容,而不是作为ajax请求。
resources :listings do
  resources :schedules
end
def new
  @listing = Listing.new
  @schedule = @listing.schedules.build
end

def edit
  @listing = Listing.find(params[:id])
  @schedule = @listing.schedules.build
end