0

我剛剛在我的Rails 4應用程序中安裝了paper_trail gem。Rails 4 x paper_trail:nil的undefined方法:破壞後的NilClass

所以,現在我有這個在我的schema.rb

create_table "versions", force: :cascade do |t| 
    t.string "item_type", null: false 
    t.integer "item_id", null: false 
    t.string "event",  null: false 
    t.string "whodunnit" 
    t.text  "object" 
    t.datetime "created_at" 
end 

我加paper_trailPost型號:

class Post < ActiveRecord::Base 
    has_paper_trail 
end 

一個posthas_manycommentsbelongs_to一個calendar

我想在我的Calendars#Index視圖中顯示最近修改過的帖子的歷史記錄。

我用official documentationthis tutorial作爲靈感。

所以,在calendars_controller.rb,我有:

def index 
    @user = current_user 
    @calendars = @user.calendars.all 
    @comments = @user.calendar_comments.where.not(user_id: @user.id).order "created_at DESC" 
    @versions = PaperTrail::Version.order('id desc').limit(20) 
end 

在我Calendarindex.html.erb觀,我有:

<h3 class="main_title">Updates</h3> 

    <div id="my_changes"> 

     <% if @versions.any? %> 

     <table id="my_change_table"> 

      <tr> 
      <th><span class="glyphicon glyphicon-calendar" aria-hidden="true"></span> CALENDAR </th> 
      <th><span class="glyphicon glyphicon-list" aria-hidden="true"></span> POST </th> 
      <th><span class="glyphicon glyphicon-user" aria-hidden="true"></span> AUTHOR </th> 
      <th><span class="glyphicon glyphicon-edit" aria-hidden="true"></span> CHANGE </th> 
      </tr> 

      <% @versions.each do |version| %> 

      <% post = Post.find_by_id(version.item_id) %> 

      <tr> 
       <td><%= Calendar.find_by_id(post.calendar_id).name %></td> 
       <td><%= post.subject %></td> 
       <td><%= User.find_by_id(version.whodunnit).first_name %></td> 
       <td><%= version.event.humanize + "d" %></td> 
      </tr> 

      <% end %> 

     </table> 

     <% else %> 

     <p>There was no change to your posts yet.</p> 

     <% end %> 

    </div> 

其實,這工作得很好,當一個用戶update是個崗位。

然而,一旦用戶destroy SA後,我收到以下錯誤:

NoMethodError in Calendars#index 
undefined method `item_id' for #<Post:0x007fff22e28c58> 
<% post = Post.find_by_id(version.item_id) %> 

事實上,這是有道理的,因爲我們destroy愛德post,它不存在了,所以我們可以檢索它的id

但我認爲這正是paper_trail的工作。

所以,我必須錯過一些東西。

我試圖使用version.reifyversion.previous方法,但仍遇到同樣的問題。

任何想法如何使這項工作?

+1

可能是錯誤中的代碼與您發佈的代碼之間存在錯位? '%post = Post.find_by_id(version.item_id)%>'? – davidrac

+0

是的,你是絕對正確的。當我提出問題時,我嘗試了不同的事情,這導致了混淆,對此感到抱歉。我只是用代碼更新了問題。非常感謝你的幫助。 –

回答

1

問題是,在你銷燬一個對象後,reify會重新運行一個未保存且沒有id的對象的新實例。

由於無論如何它被刪除,您應該預計Post.find_by_id(version.item_id)無法找到它。

編輯

你應該能夠得到從版本的原始對象的屬性(見here

所以,你可以在你的代碼更改爲類似(假定所有版本中你的系統是日曆),我認爲它應該可以工作:

 <% @versions.each do |version| %> 

     <% post = version.reify %> 

     <tr> 
      <td><%= Calendar.find_by_id(post.calendar_id).name %></td> 
      <td><%= post.subject %></td> 
      <td><%= User.find_by_id(version.whodunnit).first_name %></td> 
      <td><%= version.event.humanize + "d" %></td> 
     </tr> 

     <% end %> 
+0

好的,我明白你的意思,這很有道理。我試圖實現的是將所應用更改的列表(例如:已保存)顯示給每個帖子對象。目前的問題是,我似乎無法在銷燬之後檢索對象的ID。這讓我感到困惑,因爲我認爲這正是paper_trail的目的。我可以問你,我想達到什麼實際上是可能的嗎? –

+0

如果您只想在UI中顯示verstion,則可以執行的操作是調用reify,它將爲您提供與該版本對應的未保存的對象,並將其顯示在UI中。無需查找數據庫中的對象 – davidrac

+0

感謝您更新您的答案。我應該在'destroy'動作上使用'before_filter'來獲得'post'的'id'嗎?沒有辦法通過'paper_trail'直接實現這一點嗎? –

相關問題