Skip to content

Preview moderation changes

Jan Berdajs edited this page May 12, 2013 · 7 revisions

You may need to enable database transactions to enable preview functionality. In most cases they should already be enabled by default.

Get a live ActiveRecord preview

Use live_preview if you need to have real ActiveRecord associations on the preview. For example if you need to call where on the association:

post.comments.where(...)

live_preview will create a database transaction in which the moderation is applied. After you are done the transaction will be rolled back, so you can only use the preview inside the live_preview block. Do not try to use the live preview object outside of the block!

moderation.live_preview do |preview|
  preview.some_attr # => "new value"
  # note how we need to use .previous_changes when using live_preview,
  # .changes will be blank as the record has already been saved to DB
  preview.previous_changes # => {"attr"=>["old", "new"]}
  preview.some_association.first # => AR object
end

Whatever you do in the block, no matter on which model, will not be saved to the database.

Read-only fake preview

Whenever you can, use live_preview (read above). There are some performance issues with “fake” preview at the moment, if you have a lot of models in associations.

Allows you to see the value of all attributes, as well as all the associations (including non-moderated, except the moderations association). It is a real ActiveRecord object, so it supports dirty tracking (api.rubyonrails.org/classes/ActiveModel/Dirty.html).

The drawback is that association methods (preview.some_association) are not real ActiveRecord relations, but simple Arrays. This means you cannot call methods like where() on them. If you really need real relations, look at live_preview.

preview = moderation.preview
preview.some_attr # => "new value"
preview.some_attr_change # => ["old value", "new value"]
preview.some_association.first # => AR object

This preview is cached from applying the moderation in a transaction and then rolling it back (so it does not affect the database). The record and all associated records are frozen so they cannot be accidentally modified.

Warning: if you have custom model methods that return other ActiveRecord records, those records will not be frozen, so if you save them, those changes WILL be written to the database.

Using the preview to modify the moderation

The preview described above has a nifty feature that allows you to update attributes in the moderation by manipulating the fake object. Right now it can only handle attributes and not associations, but that might change in the future. See example below on how to use this feature.

moderation.parsed_data # => {:attributes=>{"title"=>"Task 1"}}
preview = moderation.preview(:saveable => true)
preview.title = "Task 2"
preview.title # => "Task 1" *note the change is not reflected here*
preview.update_moderation
moderation.parsed_data # => {:attributes=>{"title"=>"Task 2"}}
moderation.accept
Task.first.title # => "Task 2"

Example of using preview in your show action

In this example I allow admin users to add a preview parameter to the URL to see the preview of how the record will look after applying a moderation, without having to change code in the views.

def show
  @doctor = Doctor.find(params[:id])

  if current_admin_user && params[:preview]
    @doctor.moderations.find(params[:preview]).live_preview do |preview|
      @doctor = preview
      render :action => "show"
    end
  else
    render :action => "show"
  end
end