我有一个类似的模型,记录用户喜欢哪条记录。我使用了多态关联,因此用户可以喜欢很多模型。
目前我使用嵌套资源来处理喜欢的内容。
POST /items/:item_id/likes
DELETE /items/:item_id/likes/:id
现在由于某些原因,我想通过设计更好的路线来摆脱like_id
的使用。这是因为缓存片段视图会更容易。
请注意,item
模型只是少数likable
模型中的一个,我希望尽可能避免代码重复。
设计不使用like_id
的路由和控制器的好方法是什么,但也允许在控制器中更好地重用代码?
可能的实施
我在考虑这样的路线:
POST /items/:item_id/like
DELETE /items/:item_id/like
我不会使用嵌套的资源。相反,我在项目控制器中放置like
操作。它将确定请求是POST
还是DELETE
并采取相应措施。然而,这并不觉得干。
答案 0 :(得分:1)
我不一定知道Rails,但是在Zend Framework中我会创建一个前端控制器插件,用方法'LIKE'和'UNLIKE'将所有请求路由到特定的控制器,然后控制器推断出请求的路由,然后请求了哪个资源,然后执行必要的操作以“请求”或“不同”请求用户名称中的该资源。
为什么呢?因为用户“喜欢”或“不喜欢”有问题的资源,而不是“创建类似”或“删除类似”。当然,在后端,'like'是创建或删除的缓存或数据库中的记录 - 但资源的语义不一定等于用于持久保存该资源的方法。
答案 1 :(得分:0)
您需要的是奇异资源。
<强>的routes.rb 强>
resources :items do
resource :like, only: [:create, :destroy]
end
<强> likes_controller.rb 强>
class LikesController < ApplicationController
before_action :load_likeable
def create
@like = Like.where(likeable: @likeable, user: current_user).first_or_create
redirect_back(fallback_location: @likeable)
end
def destroy
@like = Like.find_by(likeable: @likeable, user: current_user).destroy
redirect_back(fallback_location: @likeable)
end
private
def load_likeable
klass = [Recording].detect { |c| params["#{c.name.underscore}_id"] }
@likeable = klass.find(params["#{klass.name.underscore}_id"])
end
end
<强> likes_helper.rb 强>
module LikesHelper
def like_button_for(item)
if item.liked
form_tag recording_like_path(item), method: :delete do
button_tag "UnLike"
end
else
form_tag recording_like_path(item), method: :post do
button_tag "Like"
end
end
end
end
item.liked是来自Item model
的方法