Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete as Boolean or TimeStamp or DateTime #58

Closed
frnco opened this issue Jun 30, 2014 · 7 comments
Closed

Delete as Boolean or TimeStamp or DateTime #58

frnco opened this issue Jun 30, 2014 · 7 comments
Labels
Milestone

Comments

@frnco
Copy link

frnco commented Jun 30, 2014

From what I gather, there's no option to customize how deletion is dealt with. In many cases we want to "soft delete" records so as not to lose the information. If this is not a feature, it could be a great addition to express-admin.

@simov
Copy link
Owner

simov commented Jun 30, 2014

I think I understand the text of this issue, but not the title. Can you elaborate on this one?

@frnco
Copy link
Author

frnco commented Jun 30, 2014

Yes. Basically I have a situation where I need to be able to seet a TINYINT column = 1 to say "This has been deleted", but a deletedAt field (Like Rails or Sequelize use) would be a great option too. I'd imagine having both is ideal, but I understand they're two separate things, and since deletedAt is the standard today, I believe it's the most needed one.

I'll give an example I have working and I'm trying to adapt it to Express Admin:

"categories": {
    "slug": "categories",
    "table": {
        "name": "categories",
        "pk": "id",
        "verbose": "Categories"
    },
    "columns": [
        {
            "name": "id",
            "verbose": "id",
            "control": {
                "text": true
            },
            "type": "int(11)",
            "allowNull": true,
            "defaultValue": null,
            "listview": {
                "show": false
            },
            "editview": {
                "show": true
            }
        },
        {
            "name": "name",
            "verbose": "Name",
            "control": {
                "text": true
            },
            "type": "varchar(255)",
            "allowNull": false,
            "defaultValue": null,
            "listview": {
                "show": true
            },
            "editview": {
                "show": true
            }
        },
        {
            "name": "deleted",
            "verbose": "deleted",
            "control": {
                "text": true
            },
            "type": "tinyint(1)",
            "allowNull": false,
            "defaultValue": "0",
            "listview": {
                "show": true
            },
            "editview": {
                "show": true
            }
        },
        {
            "name": "createdAt",
            "verbose": "createdAt",
            "control": {
                "text": true
            },
            "type": "datetime",
            "allowNull": false,
            "defaultValue": "0000-00-00 00:00:00",
            "listview": {
                "show": true
            },
            "editview": {
                "show": true
            }
        },
        {
            "name": "updatedAt",
            "verbose": "updatedAt",
            "control": {
                "text": true
            },
            "type": "datetime",
            "allowNull": false,
            "defaultValue": "0000-00-00 00:00:00",
            "listview": {
                "show": true
            },
            "editview": {
                "show": true
            }
        }
    ],
    "mainview": {
        "show": true
    },
    "listview": {
        "order": {},
        "page": 25
    },
    "editview": {
        "readonly": false
    }
}

@simov
Copy link
Owner

simov commented Jun 30, 2014

If you want to set fields containing application generated values (like created_at, deleted_at, generated guid for id and so on), you should use the events

There is no API for this, so you should take a look at the examples and here

The workflow is as follows:
1 add a breakpoint at the top of the event (write debugger;)
2 run the admin with --debug-brk flag
3 use node-inspector to see what you have in the args var

Basically this isn't an event either but rather just a function called right before/after the database is updated. So you can use that to set things on your own.

These pre/save callback are very flexible, in fact you can write in them whatever you want to. It requires a bit knowledge about the admin args though. Also this event code is part of your project's configuration, and it's completely out of the admin's core code.

Let me know if I'm missing something.

@frnco
Copy link
Author

frnco commented Jun 30, 2014

@simov the Events are pretty great, I didn't think about using them like this.

We're still left with the deletion issue. How should we go about listing only WHERE deletedAt IS NULL or WHERE deleted=0 ?

@simov
Copy link
Owner

simov commented Jun 30, 2014

Apparently we need more events not just pre/post save. Actually this was the initial idea, but the pre/post save were the most urgent. I think this can go in the next release.
Essentially you'll have to modify the query for the list view, but yeah currently it's not possible. I think I can have it these days, you can watch the project to get notifications when I'm pushing stuff.

@simov simov added this to the 1.2.4 milestone Jun 30, 2014
@simov simov added the feature label Jun 30, 2014
@simov
Copy link
Owner

simov commented Jul 2, 2014

👋 I just added an example for storing a soft deleted record, and then filtering only to those that are not soft deleted (btw that's the new 'event')

So the workflow is as usual using the debugger heavily to get an idea what's in args. The example is very well commented.

You need to write tests for your events, and execute them each time you install new version of express-admin (just in case)

In short: inside the preSave event I'm tricking the admin to think that it updates a record instead of removing it.

Inside the preList event first I'm checking if the user actually insist on showing the soft deleted records by using the filter widget (I thought it might be useful to see only the soft deleted records + you can filter by deleted_at also)

Next I'm modifying the generated query for the listview by adding some conditions to it, also to the query partials that are used for creating the pagination query after that.

I'm closing this, let me know if there is anything else.

@simov simov closed this as completed Jul 2, 2014
@simov
Copy link
Owner

simov commented Jul 27, 2014

@ellahn I just updated the events documentation

The examples are for deleting and then selecting inside the listview

The second one is a bit simplified, also you can try it out from the examples repository

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants