I have a few models with version changes I am tracking using Papertrail. I want to pull out the version for a timeline view of recent activity, but users should only see changes to models which they have permission to view.
I use Cancan to control access to all areas of the app, and the Ability class has all the business logic I need. However, it specifies the model name e.g. Post in the rulesets, whereas PaperTrail uses the Version model to store changes.
How can I (efficiently) tie the two systems together so that I can ask the DB to only return Version models where the associated model is visible to the user? I can do this by just getting the whole timeline of the whole site and looping over it in Ruby, but this is not scalable and I need to use scopes so that it happens in SQL.
A
version
is also an ActiveRecord model. That means you can incorporate it into your Ability class. You can simply doobject.versions.accessible_by(current_ability)
after you've made sure your Ability properly authorizes versions.An example could be:
This can, of course, be simplified by using
version.item
, but then you'll have to delegate the authorization check to another resource (which would enable you to simply saycan? :read, version.item
). This may or may not suit your specific situation. The method above provides more flexibility.