这是关于Rails 4 x paper_trail: filter versions by item_id with nested resources的后续问题。
- - - -
上一条问题的背景
在我的Rails 4应用程序中,我有以下模型:
class User < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :calendars, through: :administrations
end
class Administration < ActiveRecord::Base
belongs_to :user
belongs_to :calendar
end
class Calendar < ActiveRecord::Base
has_many :administrations, dependent: :destroy
has_many :users, through: :administrations
end
class Post < ActiveRecord::Base
belongs_to :calendar
end
我安装了paper_trail gem以跟踪post
模型中的更改,如documentation中所述,它就像一个魅力。
版本显示在Calendars#Index
视图中,该视图用作用户的信息中心。
- - - -
根据my previous question的答案,我现在在CalendarsController
中有以下代码:
def index
@user = current_user
@calendars = @user.calendars.all
@comments = @user.calendar_comments.order("created_at DESC").limit(20)
@versions = PaperTrail::Version.where(item_id: Post.where(calendar_id: @calendars.ids)).order('id DESC').limit(10)
end
现在出现问题:当用户销毁帖子时,与此帖子相关的所有版本都会消失。
我想要的是跟踪一个帖子,即使它被销毁,包括提到它被销毁的版本。
我怎样才能做到这一点?
答案 0 :(得分:3)
实现此目标的最简单方法是使用Paper Trail's metadata feature在每个帖子的版本记录中存储相应用户的ID。换句话说,只需稍微对数据进行非规范化即可使查询更容易。
class Post < ActiveRecord::Base
belongs_to :calendar
has_paper_trail meta: {user_id: :user_ids} # remember to add a user_id column to the versions table
def user_ids
calendar.user_ids # or whatever you need
end
end
然后,您可以在CalendarsController
:
@versions = PaperTrail::Version.where(user_id: current_user.id)
.order('id DESC')
.limit(10)
答案 1 :(得分:1)
您可以将其标记为已销毁并将其从范围中删除,而不是实际销毁帖子。这将保留其版本历史记录,并允许您在发生错误时恢复“已删除”帖子。
rails g migration AddDeletedToPosts deleted:boolean
如果您不再需要帖子及其版本历史记录(例如一段时间后),您可以创建垃圾收集器以永久删除或迁移到单独的存档。
版本只属于它正在跟踪的对象 - 在本例中是一个帖子。因此,当你销毁一个帖子时,你实际上是孤立它的所有版本。是的,它们确实存在于数据库中并存在于所有版本的查询中,但您不能再将它们作为范围,因为它们与任何内容都无关。这就是为什么我建议几乎销毁帖子,直到你不再关心它的版本历史。这有什么意义吗?