0

不久前,我在 paper_trail gem 上的这个 railscasts 中实现了一个“撤消”和“重做”按钮。直到今天“重做”停止工作时,一切都很好。我一直无法弄清楚为什么。

这是相关的控制器操作:

  def revert
  @version = PaperTrail::Version.find(params[:id])
    if @version.reify
      @version.reify.save!(:validate => false)
      view_context.reify_associations(@version)
    else
      @version.item.destroy
    end
    link_name = params[:redo] == "true" ? "undo" : "redo"
    link = view_context.link_to(link_name, revert_version_path(@version.next, :redo => !params[:redo]), :method => :post)
    if @version.event == "create"
      flash[:success] = "Undid #{@version.event}. #{link}"
      redirect_to :controller => session[:controller], action: :index
    else
      flash[:success] = "Undid #{@version.event}. #{link}"
      redirect_to :back
    end

  end

它在线上失败:link = view_context.link_to(link_name, revert_version_path(@version.next, :redo => !params[:redo]), :method => :post)

出现错误:ActionController:UrlGenerationError... No route matches {:action=>"revert", :controller=>"versions", :format=>nil, :id=>nil, :redo=>false} missing required keys: [:id]
所以,很明显,我按照错误来查看为什么 :id 没有被传入,但确实如此。

在参数中:

{"_method"=>"post", "authenticity_token"=>"6/B1YDXqZ62+DqMMdcYTfCTIJGaVvc1RjKmxWW2GkeQ=", "redo"=>"true", "id"=>"29"}

id 是明确定义的,这个控制器的第一行会根据这个 id 在表中找到对应的版本。

我无法弄清楚这里出了什么问题,因此将不胜感激任何帮助。

4

1 回答 1

0

对于后来发现这一点的任何人,我遇到的问题是我的条件 ( @version.reify) 的第一个语句从未返回 nil。这是因为我已经覆盖了对象属性以添加其他信息来创建事件。为了解决这个问题,我只是改变了条件来检查事件的类型,即

if @version.event == "create"
...
end

PaperTrail 的 reify 方法查看object属性@version并从序列化中重新创建对象。只要对象字段为 nil,它就会返回 nil,否则它将返回它未序列化的对象。

于 2014-07-29T16:45:54.267 回答