Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

doctrine act as signable plugin - new releases

After few months, new versions 1.2.2 and 1.2.3 of sfDoctrineActAsSignablePlugin have been released. In short, the plugin provides a Signable behavior which automatically stores information on who has created or updated a given object.


what's new

A fellow symfony developer, Daniel M├Âllenbeck, suggested that there are some options missing in the behavior configuration. Until version 1.2.1, the onDelete option was hardcoded as CASCADE, which - as Daniel emphasised - may cause problems when a given user is supposed to be deleted (physically from the database, not softDeleted).


ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE CASCADE;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE CASCADE;

Let's imagine user enters customers over and over, then leaves the company. Now the admin deletes the user - probably the hard way (directly on the database, maybe the user is auto-created from somewhere...) --> The constraint will trigger the deletion of all customers created by that user. I have some doubt anybody would be happy about that.

Having the constraint like that does the trick:

a) allow NULL values in created_by/updated_by columns:

ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE SET NULL;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE SET NULL;

b) forbid the deletion of the user:

ALTER TABLE customer
ADD CONSTRAINT customer_created_by_sf_guard_user_id
FOREIGN KEY (created_by)
REFERENCES sf_guard_user(id)
ON DELETE RESTRICT;

ALTER TABLE customer
ADD CONSTRAINT customer_updated_by_sf_guard_user_id
FOREIGN KEY (updated_by)
REFERENCES sf_guard_user(id)
ON DELETE RESTRICT;

c) do nothing

moreover


Another fellow symfony developer, Christoph Berg, helped me to trace the bug with fixtures on created_by/updated_by values. Now, the bug is fixed and all fixture data works perfectly.


the community


Taking the opportunity, I'd like to thank Daniel, Christoph and all other symfony developers who share their opinions on my work - they help to find bugs and suggest some good ideas on how to improve the code. Thanks to you, the plugin gets better and better all the time. Thanks, guys!


Please, feel free to share your opinion and comment on the plugin!

6 comments:

  1. Nice, I just discovered your plugin and I'm really happy to. Thanks ;)

    ReplyDelete
  2. Hi,

    What do you think about adding `deleted_by` field to this behavior when you also use SoftDelete behavior?

    ReplyDelete
    Replies
    1. I think it's useless. I just use both behaviors (Signable and SoftDelete) at the same time and it works fine (I used dozens of such models). Try it out ;)

      Delete
  3. Hi,

    I'm trying to use this plugin with sfDoctrineGuard and whenever I save or create a new "Signable" object I get a duplicate key reference integrity error because somehow doctrine decides to add a new user in the sf_guard_user table.
    The schema looks like this:

    Client:
    actAs: [Timestampable, Signable] <- so default Signable config...
    columns:
    ......


    Can you please tell me if you've seen this error before ?

    Thanks,
    Alex

    ReplyDelete
    Replies
    1. I'm pretty sure that
      actAs: [Signable]
      and
      actAs:
      Signable: ~
      makes no difference. sfDoctrineGuard with Signable behavior should just reference itself.

      Delete
  4. I was searching for symfony developer and landed up onto your column and i ought say thank you for sharing such practical information.

    ReplyDelete