删除嵌套属性rails

时间:2013-04-05 21:34:33

标签: ruby-on-rails ruby-on-rails-3 nested-attributes destroy

我有一个Post模型

has_many photos 

Post模型有

accepts_nested_attributes_for :photos

在我的帖子编辑表单中,我显示当前与帖子相关联的所有图像

<% for photo in @post.photos %>
  <%= image_tag(photo.avatar.url(:thumb)) %> <%= link_to "Remove Photo", post_photo_path(@post, photo), :method => :delete %>
<% end %>

将鼠标悬停在“删除照片”链接上时,路径如此

http://localhost:3000/posts/17/photos/45

我得到了未初始化的常量PhotosController,但这是预期的,因为没有。

我的问题是我是否创建了一个并在其中进行了删除操作,只会删除该照片。这是采用它的方式还是有更好的方法?

修改

照片控制器

 def destroy
  @photo = Photo.find(params[:id])
  @photo.destroy
  redirect_to edit_post_path, :notice => "Successfully deleted Photo"
 end

路线

resources :posts do
resources :photos
resources :departments
end

Rake Routes

edit_post GET    /posts/:id/edit(.:format)

由于

2 个答案:

答案 0 :(得分:3)

您描述的选项,调用destroy的{​​{1}}操作,肯定会起到作用,可能是更简单,更快捷的解决方案。请注意,如果用户对帖子的其他方面进行了更改,然后单击链接以相同的形式删除照片,则他们的更改可能会丢失。但是,使用AJAX可能有助于缓解这种担忧。

另一个选择是利用rails现有的嵌套表单支持。因为您已经使用了PhotosController的嵌套表单,所以您只有一半。如果你还没有看到这个,请查看Ryan Bates关于嵌套表格的播客:

http://railscasts.com/episodes/196-nested-model-form-part-1
http://railscasts.com/episodes/197-nested-model-form-part-2

如果你愿意支付(相信我,这是值得的),修改后的解决方案会更好一点:
http://railscasts.com/episodes/196-nested-model-form-revised

您感兴趣的肉和土豆是播客的中间到结尾,Ryan使用嵌套元素的参数中隐藏的accepts_nested_attributes_for字段来指示控制器而不是父对象更新后,应该销毁嵌套关联。

您还可以找到一个现成的gem,它包含了Ryan从头开始实现的相同Rails / Javascript功能。我过去曾使用cocoon而且非常高兴。

这种技术有点复杂,但在这种情况下我更倾向于它,因为表单的焦点是修改Post,而不是Photo。在第一个解决方案中,您必须将_destroy操作重定向回到表单。或者如果您使用AJAX,那么您必须编写为Post HTML布局量身定制的javascript,以便在元素被销毁后正确隐藏/删除元素。对于小型应用程序来说这可能没问题,但随着项目的增长,您可能会发现自己尝试将相同的PhotosController#destroy用于其他工作流程,并且可能会变得难以维护。

答案 1 :(得分:1)

我的观点是,最好的办法是创建一个PhotosController来处理破坏行为。这样,您将保留单一责任原则,并且添加自定义路线的解决方法较少。

此外,如果您确定不会添加与照片相关的任何其他操作(例如标记照片或其他任何内容),则可以选择将该操作放在PostsController中。

这完全取决于你,但我相信第一个更容易。

如果您使用第二个选项,请确保在PostsController中为销毁照片操作创建路线,并且该链接应指向该确切操作。

您的routes.rb

resources :posts do
   resources :photos, :only => [:destroy]
   resources :departments
end