带有嵌套资源的form_for [英] form_for with nested resources

查看:62
本文介绍了带有嵌套资源的form_for的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于form_for和嵌套资源的两部分问题.假设我正在编写博客引擎,并且想将评论与文章相关联.我定义了一个嵌套资源,如下所示:

I have a two-part question about form_for and nested resources. Let's say I'm writing a blog engine and I want to relate a comment to an article. I've defined a nested resource as follows:

map.resources :articles do |articles|
    articles.resources :comments
end

评论形式位于文章本身的show.html.erb视图中,例如,如下所示:

The comment form is in the show.html.erb view for articles, underneath the article itself, for instance like this:

<%= render :partial => "articles/article" %>
<% form_for([ :article, @comment]) do |f| %>
    <%= f.text_area :text %>
    <%= submit_tag "Submit" %>
<%  end %>

这将产生错误,将id称为nil,可能会错误地以此类推".我也尝试过

This gives an error, "Called id for nil, which would mistakenly etc." I've also tried

<% form_for @article, @comment do |f| %>

可以正确渲染,但是将f.text_area与文章的文本"字段相关联,而不是与评论的字段相关联,并在该文本区域中显示article.text属性的html.所以我似乎也有这个错误.我想要的是一种表单,其提交"将调用CommentsController上的create动作,并在params中带有article_id,例如对/articles/1/comments的发布请求.

Which renders correctly but relates f.text_area to the article's 'text' field instead of the comment's, and presents the html for the article.text attribute in that text area. So I seem to have this wrong as well. What I want is a form whose 'submit' will call the create action on CommentsController, with an article_id in the params, for instance a post request to /articles/1/comments.

我的问题的第二部分是,创建注释实例的最佳方法是什么?我正在ArticlesController的show动作中创建一个@comment,因此comment对象将在form_for帮助器的范围内.然后,在CommentsController的create动作中,我使用从form_for传入的参数创建新的@comment.

The second part to my question is, what's the best way to create the comment instance to begin with? I'm creating a @comment in the show action of the ArticlesController, so a comment object will be in scope for the form_for helper. Then in the create action of the CommentsController, I create new @comment using the params passed in from the form_for.

谢谢!

推荐答案

Travis R是正确的. (我希望我能投票赞成.)我只是自己完成了这项工作.使用这些路线:

Travis R is correct. (I wish I could upvote ya.) I just got this working myself. With these routes:

resources :articles do
  resources :comments
end

您将获得以下路径:

/articles/42
/articles/42/comments/99

路由到位于

app/controllers/articles_controller.rb
app/controllers/comments_controller.rb

就像在 http://guides.rubyonrails.org/routing.html上所说的一样#nested-resources ,没有特殊的名称空间.

just as it says at http://guides.rubyonrails.org/routing.html#nested-resources, with no special namespaces.

但是局部和形式变得棘手.请注意方括号:

But partials and forms become tricky. Note the square brackets:

<%= form_for [@article, @comment] do |f| %>

最重要的是,如果您需要URI,则可能需要以下内容:

Most important, if you want a URI, you may need something like this:

article_comment_path(@article, @comment)

或者:

[@article, @comment]

,如 http://edgeguides.rubyonrails中所述.org/routing.html#creating-paths-and-urls-from-objects

例如,在提供了comment_item用于迭代的局部集合中,

For example, inside a collections partial with comment_item supplied for iteration,

<%= link_to "delete", article_comment_path(@article, comment_item),
      :method => :delete, :confirm => "Really?" %>

Jamuraa所说的话可能在Article的背景下起作用,但对我而言却不以其他各种方式起作用.

What jamuraa says may work in the context of Article, but it did not work for me in various other ways.

关于嵌套资源的讨论很多,例如 http://weblog.jamisbuck.org/2007/2/5/nesting-resources

There is a lot of discussion related to nested resources, e.g. http://weblog.jamisbuck.org/2007/2/5/nesting-resources

有趣的是,我刚刚了解到,大多数人的单元测试实际上并未测试所有路径.当人们遵循jamisbuck的建议时,他们最终会以两种方式获取嵌套资源.通常,他们的单元测试将最简单地获得/发布:

Interestingly, I just learned that most people's unit-tests are not actually testing all paths. When people follow jamisbuck's suggestion, they end up with two ways to get at nested resources. Their unit-tests will generally get/post to the simplest:

# POST /comments
post :create, :comment => {:article_id=>42, ...}

为了测试他们喜欢的路线,他们需要这样做:

In order to test the route that they may prefer, they need to do it this way:

# POST /articles/42/comments
post :create, :article_id => 42, :comment => {...}

之所以了解这一点,是因为当我从此切换时,我的单元测试开始失败:

I learned this because my unit-tests started failing when I switched from this:

resources :comments
resources :articles do
  resources :comments
end

对此:

resources :comments, :only => [:destroy, :show, :edit, :update]
resources :articles do
  resources :comments, :only => [:create, :index, :new]
end

我想可以有重复的路线,也可以错过一些单元测试. (为什么要测试?因为即使用户从未看到过重复项,您的表单也可能隐式或通过命名路径引用它们.)但是,为了尽量减少不必要的重复项,我建议这样做:

I guess it's ok to have duplicate routes, and to miss a few unit-tests. (Why test? Because even if the user never sees the duplicates, your forms may refer to them, either implicitly or via named routes.) Still, to minimize needless duplication, I recommend this:

resources :comments
resources :articles do
  resources :comments, :only => [:create, :index, :new]
end

很抱歉,答案很长.我想没有多少人知道这些细微之处.

Sorry for the long answer. Not many people are aware of the subtleties, I think.

这篇关于带有嵌套资源的form_for的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆