代码之家  ›  专栏  ›  技术社区  ›  srboisvert

Rails&Acts版本化:你会如何不安地恢复记录?

  •  1
  • srboisvert  · 技术社区  · 17 年前

    如何以尊重REST约定和路由的方式还原记录?

    我的理解是,我的资源控制器中需要有revert_to_version函数。

    2 回复  |  直到 17 年前
        1
  •  8
  •   Milan Novota    17 年前

    我从来没有特别使用过版本化的行为,但当我遇到类似的场景时,我通常会通过属性的具体化来解决它。 换句话说,我只会为资源的实际版本号创建一个新资源。

    如。

    /resources/:id/actual_version
    

    PUT /resources/:id/actual_version
    :version = 123
    

    将我们的资源恢复到版本123。

    按照惯例,我会使用类似“倒数第二个”的值:version来指代实际版本之前的版本。

    然后,要回滚实际版本,我们可以这样做:

    PUT /resources/:id/actual_version
    :version=last-but-one
    

    --

    扩展我自己的答案:

      map.connect   '/resources/:id/actual_version', :controller => 'resources', :action => 'set_version', :conditions => { :method => :put } 
    

    在resources_controller.rb中:

    def set_version
      @resource = Resource.find_by_id(params[:id])
      if params[:version] && @resource
        version = params[:version] == "last-but-one" ? @resource.versions.last : params[:version]
        if @resource.revert_to(version)
          # Success, everything went fine!
        else
          # Error, the resource couldn't be reverted - unexisting version?
        end
      else
        # Error, version number or resource id is missing.
      end
    end
    

    希望这能稍微澄清我之前的想法。;)

        2
  •  0
  •   August Lilleaas    17 年前

    因为您的URL是资源的路径,所以我认为修订参数是可选的。您可以省略它,获取最新版本,或明确指定版本。

    GET /pages/1
    GET /pages/1?revision=4
    

    编辑也是如此。

    GET /pages/1/edit
    GET /pages/1/edit?revision=4
    

    PUT到/pages/1将创建一个新的修订版,将版本号递增1。新版本号的创建与当前修订号无关。这只是编辑的起点。

    显然,不可能为POST到/pages(创建)指定修订。

    如果你想特别跟踪回复,而上面提到的编辑起点还不够,有一些合理的替代方案。我不是REST极客,所以我不确定你应该选择哪一个。也许这是品味的问题。

    PUT /pages/1/revisions/4
    PUT /pages/1/revert_to?revision=4
    PUT /pages/1?revision=4
    

    第一种选择的代码示例:

    # config/routes.rb
    map.resources :pages do |page|
      page.resources :revisions
    end
    
    # app/controllers/revisions_controller.rb
    class RevisionsController < ApplicationController
      def update
        @page = Page.find(params[:page_id]) # page_id is via /pages/[page_id]/revisions/4
        @revision = @page.revisions.find_by_version_number(params[:id])
        @revision.revert
      end
    end
    
    # app/models/revision.rb
    class Revision < ActiveRecord::Base
      belongs_to :page
    
      def revert
        page.revert_to(self) # or something like that..
      end
    end