0

Я использую драгоценный камень PaperTrail. У меня есть три модели: faq, subgroup и group. group имеет отношения «один ко многим» с subgroup, а subgroup имеет отношения «has-and-of-to-many». PaperTrail не поддерживает HABTM, поэтому я изменил его на has-many-through. Теперь, когда я уничтожаю faq, он возвращается с правильными ассоциациями subgroup.Rails [PaperTrail]: accepts_nested_attributes_for не восстановлен

group с другой стороны accepts_nested_attributes_for :subgroups и, похоже, почему это терпит неудачу. subgroup уничтожается всякий раз, когда его родитель group уничтожается; но PaperTrail не восстановит subgroup, когда восстанавливается родительский 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 

undo_link метода в groups_controller.rb

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 имеет и, возможно, вызывает PaperTrail для восстановления тех, которые восстанавливаются при восстановлении родительского group. Какой правдоподобный способ сделать это?

Спасибо!

Редактировать забыл добавить, что я видел this question, но у меня нет проблемы с уничтожением, просто восстановление.

+0

Как простая «проверка работоспособности» вы уверены, что '@ version.reify (: has_many => true)' заполняет ассоциацию 'subgroups', прежде чем вы вызовете' save! '? –

+0

Я бы предположил так, так как это то, что они сказали ': has_many => true' параметр для. Как я могу проверить? – Kei

ответ

0

Прежде чем уничтожить группу, я сохраняю идентификаторы ее подгрупп. Затем я передаю этот массив revert_version_path. После reify.save! в группе я вызываю revert-hm метод в versions_controller вручную reify.save подгруппы.

revert_hm в versions_controller.rb

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 

Я не сохранить идентификатор версии подгрупп, потому что они не были уничтожены еще, в котором разрушенная версия будет фактически последняя версия, которую вы хотели бы reify.save. Это также можно использовать для :tag_list из acts_taggable_on, хотя предупреждение я не могу заставить PaperTrail создавать новые версии при изменении ассоциаций или тегов.

Это грязное решение, поэтому, если у кого-то есть лучший, скажите об этом.

p.s. если вы используете elasticsearch, вам придется позвонить Model.import на вашей модели после вызова этого метода. В противном случае elasticsearch будет думать, что ваша модель не имеет этих ассоциаций.

Смежные вопросы