投票/类似资源的路线和控制器设计

时间:2012-09-24 05:50:58

标签: ruby-on-rails ruby-on-rails-3 rest routes

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

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

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并采取相应措施。然而,这并不觉得干。

2 个答案:

答案 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

的方法