Каков наилучший способ аудита изменений в определенном поле формы? - PullRequest
0 голосов
/ 24 июня 2009

Мне нужно добавлять запись в базу данных каждый раз, когда поле изменяется в форме с указанием старого значения и нового значения.

Как бы вы поступили об этом ??

Не могли бы вы ...

  1. Добавить скрытое поле для каждого поля и сравнить его с новым значением при отправке, а затем добавить запись аудита, если необходимо ??

  2. Выберите данные для вставки в сообщение, затем сравните каждое свойство и вставьте запись аудита.

  3. Есть еще идеи?

Приветствие.

Ответы [ 5 ]

1 голос
/ 25 июня 2009

Предполагая, что вы хотите сохранить это на уровне приложения, я бы посоветовал использовать слой модели со свойствами для каждого поля для ведения журнала. Весь доступ к данным затем проходит через эту модель данных, что дает вам возможность добавить функциональность.

Пример activerecord (VBScript):

   class cSomeEntity
       public db ' link to a db wrapper
       private id, dirty, loaded ' varous flags 

       private sub class_initialize
         dirty = false
         loaded = false
       end sub

       private sub class_terminate
        if dirty then
            db.execute("update some_table set some_field=? where id=?", array(p_some_field, id))
        end if
       end sub

       public sub load_by_id(value)
         dim rs
         set rs = db.fetch_rs("select id, some_field from some_table where id=?", array(id))
         id = rs("id")
         p_some_field = rs("some_field")        
         loaded = true
       end sub

       private p_some_field
       public property get some_field
         some_field = p_some_field
       end property

       public property let some_field(value)
         if not loaded then err.raise 1, , "Entity not yet initialized, call .load_by_id() first!"
         if value <> p_some_field then
           dirty = true
           make_log_entry("some_value", p_some_field, value)           
           p_some_field = value      
         end if
       end property

       private sub make_log_entry(field, old_value, new_value)
         db.execute("insert into audit_log (table, field, old_value, new_value) values (?, ?, ?, ?)", _
           array("some_table", field, old_value, new_value))     
       end sub 
    end class

Может показаться немного раздутым, но он более гибкий, чем подход, основанный на триггерах. Например, вы можете легко реализовать проверки диапазона и тому подобное.

Во-вторых, когда вам нужно написать несколько классов сущностей, вы можете добавить много функций в класс делегата и использовать шаблон кода для написания свойства getter & setters.

0 голосов
/ 24 июня 2009

Если вы используете Postgres или любую другую базу данных, имеющую функции, вы можете легко написать для этого функцию, которая могла бы запускаться при каждом выполнении UPDATE для таблицы

Что касается пункта 1, определенно не стоит включать в форму «скрытые поля», поскольку кто-то может легко создать собственное утверждение POST.

Для пункта 2, это будет работать достаточно легко, и это то, что я бы использовал, если бы не мог написать функцию.

Ты бы хотел сделать что-то вроде этого:

  1. Подтвердите, что то, что они отправляют, действительно
  2. Выбрать информацию из необновленной строки
  3. Сохраняет как данные формы, так и данные БД в двух массивах, например $db_data и $form_data
  4. Получите различия, используя функцию array_diff_assoc

    $ разности = array_diff_assoc ($ db_data, $ form_data);

Помните, что и форма, и массив db должны иметь одинаковые ключи.

0 голосов
/ 24 июня 2009

Вы можете использовать триггер обновления в своей базе данных для сравнения и аудита. (У меня нет удобного примера кода - извините).

0 голосов
/ 24 июня 2009

Вы не говорите, какую базу данных вы используете. Вы можете попробовать написать процедуру, которая получает текущее значение и сравнивает его, сохраняя в базе данных. Я предлагаю это, как мне кажется, это скорее сравнение, которое должно выполняться на стороне базы данных, а не на стороне пользователя.

Редактировать: Эй, если вы используете Oracle, это легко написать процедуры. :)

0 голосов
/ 24 июня 2009

я думаю, что сначала вы можете сериализовать форму в строку, и сравнить с последней строкой, чтобы увидеть, если что-то изменится. если 2 строки равны, вам нечего делать.

Я предположил, что все элементы в вашей форме, названные [], как:

form_name ['first_name'] .... form_name ['last_name'] ....

если вы используете php, вы можете сделать array_diff_assoc, чтобы увидеть, что изменится.

все, что вам нужно, это каждый раз сохранять в db последний массив форм, сохранять в виде строки с помощью сериализации.

...