在 Rails 中为多态关系中的点赞按钮构建表单
Building a form for a like button in a polymorphic relationship in Rails
我正在尝试为“赞”按钮构建一个表单。这个like模型多态到不同类型的Model(评论/posts/等),属于某个用户。
例如,当此用户正在查看博客项目时,我想在 post 下方显示一个赞按钮。我设置我的路由的方式是,类似的路由总是嵌套在它们指定的多态对象中:
所以对于 posts 例如:
#routes.rb
resources :posts do
resources :likes, only: [:create, :destroy]
end
所以 post link 看起来像 /posts/:post_id/likes/
(方法:Post)
在控制器中,我创建了一个新的 Like 对象,将其分配给用户并保存。这非常有效。
问题出在我尝试创建删除表单时。我真的不知道如何创建它,我知道 link 应该是 /posts/:post_id/like/:id
(方法:删除),但是以这种方式配置它会导致错误。
我认为表单也可以重构,但我不知道如何为这些 'complex' 关系制作表单。
#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
之类的东西。因此,在尝试构建 link.
时,我不断收到 ActionController::UrlGenerationError
in PostsController#show
错误
无需使用实际表格,您可以使用 link_to。这是一个包含基本文本的示例 link(以确保其正常工作)
- 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
然后你使用 image/button 作为 link 本身。
- 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。
这应该有效:
= 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
助手的第一个参数中,你实际上并不需要它。
If the record passed to form_for is a resource, i.e. it corresponds to
a set of RESTful routes, e.g. defined using the resources method in
config/routes.rb. In this case Rails will simply infer the appropriate
URL from the record itself.
(source: 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|
我正在尝试为“赞”按钮构建一个表单。这个like模型多态到不同类型的Model(评论/posts/等),属于某个用户。
例如,当此用户正在查看博客项目时,我想在 post 下方显示一个赞按钮。我设置我的路由的方式是,类似的路由总是嵌套在它们指定的多态对象中:
所以对于 posts 例如:
#routes.rb
resources :posts do
resources :likes, only: [:create, :destroy]
end
所以 post link 看起来像 /posts/:post_id/likes/
(方法:Post)
在控制器中,我创建了一个新的 Like 对象,将其分配给用户并保存。这非常有效。
问题出在我尝试创建删除表单时。我真的不知道如何创建它,我知道 link 应该是 /posts/:post_id/like/:id
(方法:删除),但是以这种方式配置它会导致错误。
我认为表单也可以重构,但我不知道如何为这些 'complex' 关系制作表单。
#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
之类的东西。因此,在尝试构建 link.
ActionController::UrlGenerationError
in PostsController#show
错误
无需使用实际表格,您可以使用 link_to。这是一个包含基本文本的示例 link(以确保其正常工作)
- 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
然后你使用 image/button 作为 link 本身。
- 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。
这应该有效:
= 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
助手的第一个参数中,你实际上并不需要它。
If the record passed to form_for is a resource, i.e. it corresponds to a set of RESTful routes, e.g. defined using the resources method in config/routes.rb. In this case Rails will simply infer the appropriate URL from the record itself. (source: 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|