Rails [PaperTrail]:accepted_nested_attributes_for未恢复

时间:2015-07-22 16:42:43

标签: ruby-on-rails ruby-on-rails-4 nested-attributes paper-trail-gem

我正在使用PaperTrail宝石。我有三个模型faqsubgroupgroupgroupsubgroup有一对多的关系,subgroup有一个属于多对多的关系。 PaperTrail不支持HABTM,因此我将其更改为has-many-through。现在当我销毁一个faq时,它会被恢复为正确的subgroup关联。

另一方面,{p> group accepts_nested_attributes_for :subgroups似乎是它失败的原因。只要其父subgroup被销毁,group就会被销毁;但是当父subgroup恢复时,PaperTrail将无法恢复group。但是,我可以看到有subgroup的版本,PaperTrail没有被调用来恢复它们。我怎么能这样做?

group.rb

class Group < ActiveRecord::Base
    has_many :subgroups, :dependent => :destroy, inverse_of: :group
    validates :name, presence: true
    #validates :subgroups, length: { minimum: 1 }
    accepts_nested_attributes_for :subgroups, :allow_destroy => true
    has_paper_trail
end

subgroup.rb

class Subgroup < ActiveRecord::Base
    belongs_to :group, inverse_of: :subgroups
    has_many :faqs_subgroups
    has_many :faqs, through: :faqs_subgroups
    validates :name, presence: true
    validates_presence_of :group
    has_paper_trail
end

versions_controller.rb

class VersionsController < ApplicationController
    def revert
        @version = PaperTrail::Version.where(:id => params[:id], :item_type => params[:item_type], :item_id => params[:item_id])[0]

        if params[:item_type] == "Group"
            if @version.reify(:has_many => true)
                @version.reify(:has_many => true).save!
            else 
                @version.item.destroy
            end
        else
            if @version.reify
                @version.reify.save!
            else
                @version.item.destroy
            end
        end

        link_name = params[:act] == "undo" ? "redo" : "undo"
        link = view_context.link_to(link_name, revert_version_path(@version.next, :item_type => params[:item_type], :item_id => params[:item_id], :act => "redo"), :method => :post)

        if @version.event == "create" && params[:item_type] == "Faq"
            redirect_to faqs_path, :notice => "Successfully undid #{@version.event}. #{link}"
        elsif @version.event == "create" && params[:item_type] == "Group"
            redirect_to groups_path,  :notice => "Successfully undid #{@version.event}. #{link}"
        else
            redirect_to :back, :notice => "Successfully undid #{@version.event}. #{link}"
        end
    end
end

groups_controller.rb中的undo_link方法

def undo_link
  view_context.link_to("undo", revert_version_path(@group.versions.last, :item_type => "Group", :item_id => @group.id, :act => "undo"), :method => :post)
end

如果PaperTrail不支持还原subgroup,我正在考虑保存group所有子组的ID和版本ID,并且可能会调用PaperTrail来恢复父group时的那些子组。恢复。这样做有什么可行的方法?

谢谢!

修改忘记添加我已经看过this question,但我没有遇到破坏问题,只是恢复。

1 个答案:

答案 0 :(得分:0)

当前解决方案: 在销毁组之前,我保存其子组的ID。然后,我将该数组传递给revert_version_path。在群组reify.save!之后,我在revert-hm中调用versions_controller方法手动reify.save子群。

版本_controller.rb中的revert_hm

def revert_hm(item_type, item_id)
    @version = PaperTrail::Version.where(:item_type => item_type, :item_id => item_id).last
    if @version.reify != nil
        @version.reify.save!
    else
        @version.item.destroy
    end
end

我不保存子组的版本ID,因为它们尚未被销毁,其中销毁的版本实际上是您希望reify.save的最新版本。这也可用于:tag_list acts_taggable_on,但警告我无法让PaperTrail在更改关联或标签时制作新版本。

这是一个混乱的解决方案,所以如果有人有更好的解决方案,请说出来。

P.S。如果您使用的是elasticsearch,则必须在调用此方法后调用模型上的Model.import。否则,elasticsearch会认为您的模型没有这些关联。