简体   繁体   English

删除嵌套的属性栏

[英]Remove nested attribute rails

I have a Post model that 我有一个帖子模型

has_many photos 

The Post model has 邮政模型有

accepts_nested_attributes_for :photos

In my Post edit form i show all the images that are currently associated with the post 在我的帖子编辑表单中,我显示了当前与该帖子关联的所有图像

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

When hovering over over the Remove Photo link the path looks like so 将鼠标悬停在“删除照片”链接上时,路径如下所示

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

I get uninitialized constant PhotosController, but that's expected as there isn't one. 我得到了未初始化的常量PhotosController,但这是可以预期的,因为没有一个。

My question is do i create one and have a destroy action in there that will just delete that photo.. Is this the way to go about it or is there a better way? 我的问题是,我是否要创建一个照片并在其中进行销毁操作,而该操作只会删除该照片。这是解决该问题的方法还是有更好的方法?

EDIT 编辑

Photos Controller 照片控制器

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

Routes 路线

resources :posts do
resources :photos
resources :departments
end

Rake Routes 耙道

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

Thanks 谢谢

The option you described, invoking the destroy action of a PhotosController , would certainly do the trick and would probably be the simpler and quicker solution. 您描述的选项(调用PhotosControllerdestroy动作)肯定可以解决问题,并且可能是更简单,更快捷的解决方案。 Be careful that if a user makes changes to other aspects of the Post and then clicks a link to delete the Photo in the same form, their changes would probably get lost. 请注意,如果用户对帖子的其他方面进行了更改,然后单击链接以相同的形式删除照片,则他们的更改可能会丢失。 However, using AJAX might help alleviate this concern. 但是,使用AJAX可能有助于减轻这种担忧。

Another option would be to leverage rails existing support for nested forms. 另一种选择是利用Rails对嵌套表单的现有支持。 Because you are already using a nested form with accepts_nested_attributes_for you're about halfway there. 因为您已经使用了一个带有accepts_nested_attributes_for的嵌套表单,因为您已经到了一半。 If you haven't seen this yet, check out Ryan Bates' podcast on Nested Forms: 如果尚未看到此内容,请查看嵌套表单上的Ryan Bates播客:

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

And if you're willing to pay (trust me, it's worth it), the revised solution is a little nicer: 如果您愿意付款(相信我,这是值得的),那么修订后的解决方案会更好一些:
http://railscasts.com/episodes/196-nested-model-form-revised http://railscasts.com/episodes/196-nested-model-form-revised

The meat and potatoes of what you're interested in is towards the middle to the end of the podcast where Ryan uses the hidden _destroy field in the nested element's params to indicate to the controller than when the parent object is updated, the nested association should be destroyed. 您感兴趣的内容是在播客的中间到结尾处,其中Ryan使用嵌套元素的参数中的隐藏_destroy字段来向控制器指示,而不是在更新父对象时,嵌套关联应该被摧毁。

You can also find an off the shelf gem that wraps up this same Rails/Javascript functionality that Ryan implemented from scratch. 您还可以找到一个现成的宝石,它包装了Ryan从头开始实现的相同的Rails / Javascript功能。 I've used cocoon in the past and have been quite pleased. 我过去使用过 ,对此感到非常高兴。

This technique is a little more complicated but I tend to prefer it in this case because the focus of the form is to modify a Post, not a Photo. 这种技术稍微复杂一点,但是在这种情况下,我倾向于使用它,因为表单的重点是修改帖子,而不是照片。 In the first solution, you would have to make the PhotosController#destroy action redirect back to the form. 在第一个解决方案中,您将必须使PhotosController#destroy操作重定向回表单。 Or if you use AJAX, then you would have to write javascript that was tailored to the layout of your Post HTML to properly hide/remove the element after it was destroyed. 或者,如果您使用AJAX,则必须编写适合于Post HTML布局的javascript,以在元素被销毁后正确地隐藏/删除该元素。 This may be ok for small applications, but as the project grows you may find yourself trying to use the same PhotosController for other work-flows and that could become brittle to maintain. 这对于小型应用程序可能是可以的,但是随着项目的发展,您可能会发现自己尝试将相同的PhotosController用于其他工作流程,并且可能变得难以维护。

My opinion is that the best thing to do would be to create a PhotosController to handle the destroy action. 我认为最好的方法是创建一个PhotosController来处理destroy动作。 That way you will preserve the Single Responsibility Principle, and have less workaround with adding custom routes. 这样,您将保留“单一责任原则”,并且在添加自定义路由时具有较少的解决方法。

Also, there is the option to put that one action in the PostsController if you are really sure you won't be adding any additional actions connected to Photos (like tagging photos, or whatever). 另外,如果您确实确定不会添加与“照片”相关的任何其他操作(例如为照片添加标签等),则可以选择将该操作放入PostsController

It's really up to you, but i believe the first one is easier. 这完全取决于您,但是我相信第一个会更容易。

If your going with the second option, be sure to create a route for the destroy photo action in the PostsController and the link should be pointing at that exact action. 如果您选择第二种方法,请确保在PostsController为destroy photo动作创建一条路线,并且链接应指向该确切动作。

Your routes.rb : 您的routes.rb

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

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

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