1

我有一个类似的模型,记录哪个用户喜欢哪个记录。我使用了多态关联,因此用户可以喜欢许多模型。

目前我使用嵌套资源来处理喜欢。

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在项目控制器中放置了一个动作。它将确定请求是 aPOST还是 aDELETE并采取相应的行动。然而,这不会感觉干燥。

4

2 回答 2

1

我不一定了解 Rails,但在 Zend Framework 中,我会创建一个前端控制器插件,以将所有使用方法“LIKE”和“UNLIKE”的请求路由到特定控制器,然后推断出请求了哪个路由,然后是哪个资源请求,然后以请求用户的名义执行必要的操作以“喜欢”或“不喜欢”该资源。

为什么?因为用户是“喜欢”或“不喜欢”有问题的资源,而不是“创建喜欢”或“删除喜欢”。当然,在后端,“喜欢”是缓存或数据库中创建或删除的记录——但资源的语义不一定等同于用于持久化该资源的任何方法。

于 2012-09-24T07:08:39.993 回答
0

您需要的是奇异资源。

路线.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 模型的方法

于 2017-04-27T15:14:46.133 回答