铁轨和 行为版本控制:您将如何安全地恢复记录?

发布于 2024-07-14 03:08:42 字数 157 浏览 8 评论 0原文

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

我正在寻找如何设置我的routes.rb 并构建链接的示例 控制器执行恢复操作。 我发现的所有示例都是 REST 之前的轨道。

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

How can you revert records in a way that respects REST conventions and routing?

I am looking for examples of how to setup my routes.rb and build the link & controller action to do the revert. All the examples I have found are pre-REST rails.

My understanding is that I need to have revert_to_version function in my resource controller.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟燃烟灭 2024-07-21 03:08:42

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

例如。

/resources/:id/actual_version

将指向 id :id 的资源的实际版本号。
然后要更改实际版本,我们只需将所需的数字放入其中即可。

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

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

作为一种约定,我会使用类似“last-but-one”的内容作为 :version 的值来引用实际版本之前的版本。

然后,要回滚实际版本,我们可以执行以下操作:

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

--

扩展我自己的答案:

在routes.rb中,我们可以执行以下操作:

  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

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

I've never used acts-as-versioned in particular, but when I come across similar scenarios, the way I usually solve it is by reification of the attribute.
In other words, I'd create a new resource only for the actual version number of the resource.

Eg.

/resources/:id/actual_version

would point to the actual version number of the resource with id :id.
Then to change the actual version, we can just PUT desired number to it.

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

would revert our resource to the version 123.

As a convention, I'd use something like "last-but-one" as a value of :version to refer to the version that preceded the actual one.

Then, to rollback the actual version, we can just do:

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

--

Expanding my own answer:

In routes.rb we can do something like:

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

And in 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

Hope that clarified my previous thoughts a bit. ;)

神魇的王 2024-07-21 03:08:42

我假设您正在滚动自己的系统。 我的回答与任何特定的版本控制插件无关。

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

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

编辑也是如此。

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

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

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

如果您想特别跟踪恢复,并且上述编辑起点还不够,那么有一些明智的选择。 我不是 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

如果您采用此方案,则可能需要 GET /pages/1/revisions/4 来显示修订版 4 的页面,而不是 GET /pages/1?revision=4。

I'll assume you're rolling your own system. My answer does not relate to any particular versioning plugin.

Because your URLs are paths to resources, I would consider the revision parameter as optional. You can leave it out, and get the latest revision, or specify the revision eplicitly.

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

Same goes for editing.

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

PUT to /pages/1 would create a new revision, incrementing the version number by one. The new version number is created without regard to the current revision number. It's merely a starting point when editing.

Obviously, it should be impossible to specify a revision for a POST to /pages (create).

If you want to track reverts in particular, and the editing starting point mentioned above isn't sufficient, there are a few sensible alternatives. I'm not a REST geek, so I'm not sure which you should choose. Perhaps it's a matter of taste.

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

A code example for the first alternative:

# 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

If you roll with this, it probably makes sense to GET /pages/1/revisions/4 to display the page for revision 4, instead of GET /pages/1?revision=4.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文