我正在尝试为类似按钮构建表单。这个模型对于不同类型的模型(评论/帖子/等)是多态的,属于某个用户。
当该用户正在查看博客项目时,我想在帖子下面显示一个类似按钮。我已经设置了我的路线,其路线总是嵌套在它们所针对的多态对象中:
所以对于帖子例如:
#routes.rb
resources :posts do
resources :likes, only: [:create, :destroy]
end
所以帖子链接看起来像/posts/:post_id/likes/
(方法:发布)
在控制器中,我创建一个新的Like对象,将其分配给用户并保存。这非常有效。
问题在于我尝试创建删除表单。我真的不知道如何创建它,我知道链接应该是/posts/:post_id/like/:id
(方法:删除),但是这样配置会导致错误。
我认为表格也可以重构,但我不知道如何为这些复杂的表格制作表格。关系。
#shared/_like_button.html.haml
- if not @post.is_liked_by current_user
= form_for(@post.likes.build, url: post_likes_path(@post)) do |f|
= f.submit
- else
= form_for(@post.likes.find_by(user_id: current_user.id), url: post_like_path(@post), html: {method: :delete}) do |f|
= f.submit
我认为主要问题是post_like_path(@post)
没有正确呈现,因为我不知道:id
之类的。{1}}。因此,在尝试构建链接时,我一直遇到ActionController::UrlGenerationError
PostsController#show
错误。
答案 0 :(得分:2)
这应该有效:
= form_for([@post, @post.likes.find_by(user_id: current_user.id)], html: {method: :delete}) do |f|
代码中的 url: post_like_path(@post)
需要第二个参数(like
对象)。是什么引发了错误。
但是,如果将嵌套资源作为数组放在form_for
帮助器的第一个参数中,那么您根本不需要它。
如果传递给form_for的记录是资源,即它对应于 一组RESTful路由,例如使用资源方法定义 配置/ routes.rb中。在这种情况下,Rails将简单地推断出合适的 记录本身的URL。 (来源:http://apidock.com/rails/ActionView/Helpers/FormHelper/form_for)
如果您的资源嵌套在另一个资源中,则可以传递一组资源。
现在......您可能希望将此代码重用于其他多态模型。您可以将@post
或@comment
传递给您的部分,如下所示:
= render :partial => 'like_button', locals: {likable: @post}
并像这样重构你的部分:
= form_for([likable, likable.likes.find_by(user_id: current_user.id)], html: { method: :delete}) do |form|
答案 1 :(得分:1)
没有必要使用实际表单,您可以使用link_to。这是一个带有基本文本链接的示例(以确保它正常工作)
- if not @post.is_liked_by current_user
= link_to 'Like', post_like_path(@post), method: :post
- else
= link_to 'Delete', post_like_path([@post, @post.likes.find_by(user_id: current_user.id)]), method: :delete
然后使用图像/按钮作为链接本身。
- if not @post.is_liked_by current_user
= link_to post_like_path(@post), method: :post do
# some html image/button
- else
= link_to post_like_path([@post, @post.likes.find_by(user_id: current_user.id)]), method: :delete do
# some html image/button
在接受回答的帮助下更新了此代码,以便将来任何人都可以使用link_to。