[英]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. 您描述的选项(调用
PhotosController
的destroy
动作)肯定可以解决问题,并且可能是更简单,更快捷的解决方案。 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.