【问题标题】:Route and controller design for vote/like resource投票/类似资源的路由和控制器设计
【发布时间】:2012-09-15 14:06:10
【问题描述】:

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • 我认为你说得有道理。让我看看 Rails 等价物是什么。
    【解决方案2】:

    你需要的是单一资源。

    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 模型中的方法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-08
      • 2018-01-16
      • 1970-01-01
      • 2013-01-23
      • 2013-06-04
      • 2014-10-08
      • 2021-10-19
      • 1970-01-01
      相关资源
      最近更新 更多