Monday, September 28, 2009

View and edit deleted records with acts_as_paranoid

We at intinno use acts_as_paranoid so as not to permanently remove any data from the mysql tables. This also helps in restoring deleted data, if required.

Situation:

In Naarad(our erp solution for coaching institutes) users add teaching logs, which is basically a log book of which teacher taught which subject from what to what time. However your clients employ teachers which come and go. So teachers get added and deleted all the time. But if the teachers are deleted, then the logs refering to them would throw an error , saying the record doesn't exist.

Solution:

If we dont find the record, then try find_with_deleted first. If find with deleted fails, then render nil or blank

Basically instead of using
<td><%= log.teacher.name %></td>
view raw gistfile1.rb hosted with ❤ by GitHub

I now used
<td><%= force_find(log, "teacher", "name") %></td>
view raw gistfile1.txt hosted with ❤ by GitHub

and force_find is defined as
def force_find(object, association, association_attribute)
class_name = association.camelize.constantize
id = object.send("#{association.underscore}_id")
object = class_name.find_with_deleted(id)
object.nil? ? "" : object.send(association_attribute)
end
view raw gistfile1.rb hosted with ❤ by GitHub


Situation:

Ok now I can view the deleted record. But the logs can also be edited. So now the deleted records shoould be edited. But editing a deleted record sounded wierd.

Solution:

But there was a catch. In my case, logs corresponded to dates. So if a record is deleted, then it makes sense to edit its log entries before it was deleted. So in my app subjects had teachers and i defined a new method

def teachers_on(time)
condition =
(time && time.is_a?(Time) ?
"deleted_at is NULL OR deleted_at > '#{time.strftime("%Y-%m-%d %H:%M:%S")}' " : "")
self.teachers.find(:all, :with_deleted => true, :conditions => condition)
end
view raw gistfile1.rb hosted with ❤ by GitHub


Now while assigning teachers to log, all the teachers present on the system at a particular day are fetched.

Note: The above method in the application helper has been extracted out into a plugin. Read the details here.

1 comment:

AJ said...

Instead of using

object.nil? ? "" : object.send(association_attribute)

you can use


object.send(association_attribute) rescue ""