This is thoroughly broken, and it would be helpful if the original author could fix it. What’s Jmanager Controller, for example? I cleaned up all of the code portions, but the wiki doesn’t like something starting with a left bracket, breaking a lot of the code. Perhaps a better wiki software is needed?
1. Create a log_entry and log_level table: (here’s the migration for it)
class CreateLogEntries < ActiveRecord::Migration
def self.up
create_table :log_entries, :force => true do |t|
t.column :entry, :text
t.column :user, :string
t.column :created_at, :datetime
t.column :loglevel_id, :integer
end
do |r|
Loglevel.create(:name => r.to_s)
end
end
end
def self.down
drop_table :log_entries
drop_table :loglevels
end
2. Create model for loglevels :
class Loglevel < ActiveRecord::Base
has_many :global_settings
has_many :log_entries
end
3. Create model for log_entries:
class LogEntry < ActiveRecord::Base
validates_presence_of :entry, :created_by
belongs_to :loglevel
end
4. Now for some magick; We’re going to automagickally create methods to create log entries for each of the levels without having to specify the level. Add the following to the top of the file:
class Object
# the following is after Josh Staiger: Metaprogramming method
closures in Ruby
# http://joshstaiger.org/archives/2006/metaprogramming.html
def lexdef(method_symbol, &block)
self.class.send :define_method, method_symbol, &block
end
end
That method extends Object and allows an object to easily define new methods on the fly.
Now, within the Log Entry class, add the following:
...
# creates helper methods for us.... for each of the log levels
Loglevel.find_all.each do |l|
lexdef "create_#{l.name}_entry".to_sym do |creator, entry|
self.create(:loglevel_id => l.id,
:entry => entry,
:created_by => creator)
end
end
It goes through each of the loglevel records, and creates a method for each one, such as create_debug_entry—so that if you should add a new record in the future, you won’t have to write a method for it.
Also, it helps keep your code DRY.
4. Now add the loglevels controller:
class LoglevelsController < JmanagerController
active_scaffold :loglevel do |config|
do |action|
config.send(action).link.security_method = :admin?
end
end
end
I’ve added security, to keep people from modifying the table.
5. And now for the Log Entries Controller :
class LogEntriesController < JmanagerController
active_scaffold :log_entry do |config|
config.columns.add [:created_at]
config.actions.exclude :create
config.actions.exclude :update
config.actions.exclude :delete
list.per_page = 50
list.sorting = {:created_at => :desc}
end
end
6. Entering the home stretch … in your lib directory, create action_overrides.rb:
module ActionOverrides
# override if you want to do anything prior to destruction
def before_destroy(record); end
# override if you want to do anything after destruction
def after_destroy(record); end
...
# overridden from ActiveScaffold::Actions::Delete
def do_destroy
@record = find_if_allowed(params[:id], 'delete')
before_destroy(@record)
@record.destroy
after_destroy(@record)
end
end
As of rev 267, there is not support for hooks to perform operations before or after a delete action. This adds the functionality.
7. Additionally, in the lib, create create_log_methods.rb: require_dependency “action_overrides”
class Object
# the following is after Josh Staiger: Metaprogramming method closures in Ruby
# http://joshstaiger.org/archives/2006/metaprogramming.html
def lexdef(method_symbol, &block)
self.class.send :define_method, method_symbol, &block
end
end
module CreateLogMethods
include ActionOverrides
def creator
lexdef :before_create_save do |record|
LogEntry.create_info_entry(@session[:user],
"#{record.name} #{record.class.to_s.downcase} created.")
end
lexdef :before_update_save do |record|
LogEntry.create_debug_entry(@session[:user],
"#{record.name} #{record.class.to_s.downcase} updated: #{record.inspect}")
end
lexdef :before_destroy do |record|
LogEntry.create_info_entry(@session[:user],
"#{record.name} #{record.class.to_s.downcase} deleted. All child records also deleted.")
end
end
end
These will create (override) methods within your actions which will log the actions which have been created.
8. Finally…. In the Application Controller, application.rb, place the following at the top of the file:
require_dependency "create_log_methods"
require_dependency "action_overrides"
and within the class, place these lines:
include CreateLogMethods
before_filter :creator
A before filter is used to add the methods because otherwise
active_scaffold was overwriting the methods.
There you have it…. An easy (and dry) audit trail.