Question

Here is my code so far:

class Video < ActiveRecord::Base
  has_paper_trail meta: { athlete_id: :athlete_id, approved: false },
                  if: Proc.new { |v| v.needs_approval? }
  validate :should_be_saved?

  def should_be_saved?
    errors.add(:base, 'added for approval') if needs_approval?
  end

  def needs_approval
    @needs_approval ||= false
  end

  def needs_approval?
    @needs_approval
  end

end

# ApplicationController
class ApplicationController < ActionController::Base

  def user_for_paper_trail
    return unless user_signed_in?
    original_user.present? ? original_user : current_user
  end

  # Used to determine the contributor
  # When contributor logs in, warden saves the contributor_id in session
  def original_user
    return nil unless remember_contributor_id?
    @original_user ||= User.find(remember_contributor_id)
  end

  def info_for_paper_trail
    { athlete_id: current_user.id } if current_user
  end

end

The problem I am running into currently is when the Video object is saved the validation fails (because I told it too), but I need for the validation to fail but the version object continue with its creation. Just not too sure how to go about doing that.

EDITS
Here is my code (the code below is still using the ApplicationController code from above):

class Video < ActiveRecord::Base
  # .. other methods

  include Contributable
  attr_accessible :video_type_id, :athlete_id, :uploader_id, :created_at, :updated_at, :uniform_number, :featured,
                  :name, :panda_id, :date, :thumbnail_url, :mp4_video_url, :from_mobile_device, :duration, :sport_id,
                  :delted_at, :approved
end

module Contributable
  extend ActiveSupport::Concern

  included do
    has_paper_trail meta: { athlete_id: :athlete_id, approved: false },
                    unless: Proc.new { |obj| obj.approved? },
                    skip: [:approved]
  end

  def log_changes_or_update(params, contributor = nil)
    update_attribute(:approved, false) unless contributor.blank?

    if contributor.blank?
      update_attributes params
    else
      self.attributes = params
      self.send(:record_update)
      self.versions.map(&:save)
    end
  end

end

class VideosController < ApplicationController
  def update
    # ... other code
    # original_user is the contributor currently logged in
    @video.log_changes_or_update(params[:video], original_user)
  end
end

The app I am working on has a small layer of complexity that allows for users with a certain role to edit profiles they have access too. I am trying to save the versions of each change out (using paper_trail) without affecting the existing object.

The code above works exactly how I want it to, however, I am just curious to know if in my log_changes_or_update method is not the correct way to go about accomplishing the overall goal.

Was it helpful?

Solution

Why not just remove the validation and add an approved attribute with a default value of false to the Video model? That way the Video object is saved and a paper_trail version is created. Later when the video gets approved paper_trail will note that change too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top