{"id":13462920,"url":"https://github.com/JackDanger/permanent_records","last_synced_at":"2025-03-25T06:31:24.861Z","repository":{"id":385208,"uuid":"2498","full_name":"JackDanger/permanent_records","owner":"JackDanger","description":"Rails Plugin - soft-delete your ActiveRecord records. It's like an explicit version of ActsAsParanoid","archived":false,"fork":false,"pushed_at":"2024-04-03T09:12:08.000Z","size":1352,"stargazers_count":273,"open_issues_count":15,"forks_count":64,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-02T14:16:13.031Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://jdanger.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JackDanger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2008-03-04T19:30:54.000Z","updated_at":"2025-01-31T17:10:58.000Z","dependencies_parsed_at":"2022-07-07T12:54:54.534Z","dependency_job_id":"5ca34067-79c6-482f-8566-2f28789a0a91","html_url":"https://github.com/JackDanger/permanent_records","commit_stats":{"total_commits":250,"total_committers":34,"mean_commits":7.352941176470588,"dds":0.748,"last_synced_commit":"1ed022117f4f6e0b1e9b576cfa9ee3eeba85705a"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JackDanger%2Fpermanent_records","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JackDanger%2Fpermanent_records/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JackDanger%2Fpermanent_records/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JackDanger%2Fpermanent_records/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JackDanger","download_url":"https://codeload.github.com/JackDanger/permanent_records/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245413756,"owners_count":20611353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T13:00:40.958Z","updated_at":"2025-03-25T06:31:24.426Z","avatar_url":"https://github.com/JackDanger.png","language":"Ruby","funding_links":[],"categories":["Active Record Plugins","Ruby","ORM/ODM Extensions"],"sub_categories":["Active Record Soft Delete"],"readme":"# PermanentRecords\n\n[http://github.com/JackDanger/permanent_records/](http://github.com/JackDanger/permanent_records/)\n\nThis gem prevents any of your ActiveRecord data from being destroyed.\nAny model that you've given a \"deleted_at\" datetime column will have that column set rather than let the record be deleted.\n\n## What methods does it give me?\n\n```ruby\nUser.find(3).destroy          # Sets the 'deleted_at' attribute to Time.now\n                              # and returns a frozen record. If halted by a\n                              # before_destroy callback it returns false instead\n\nUser.find(3).destroy(:force)  # Executes the real destroy method, the record\n                              # will be removed from the database.\n\nUser.destroy_all              # Soft-deletes all User records.\n\nUser.delete_all               # bye bye everything (no soft-deleting here)\n```\nThere are also two scopes provided for easily searching deleted and not deleted records:\n\n```ruby\nUser.deleted.find(...)        # Only returns deleted records.\n\nUser.not_deleted.find(...)    # Only returns non-deleted records.\n```\n\nNote: Your normal finds will, by default, _include_ deleted records. You'll have to manually use the ```not_deleted``` scope to avoid this:\n\n```ruby\nUser.find(1)                  # Will find record number 1, even if it's deleted.\n\nUser.not_deleted.find(1)      # This is probably what you want, it doesn't find deleted records.\n```\n\n## Can I easily undelete records?\n\nYes. All you need to do is call the 'revive' method.\n\n```ruby\nUser.find(3).destroy         # The user is now deleted.\n\nUser.find(3).revive          # The user is back to it's original state.\n```\n\nAnd if you had dependent records that were set to be destroyed along with the parent record:\n\n```ruby\nclass User \u003c ActiveRecord::Base\n  has_many :comments, :dependent =\u003e :destroy\nend\n\nUser.find(3).destroy         # All the comments are destroyed as well.\n\nUser.find(3).revive          # All the comments that were just destroyed\n                             # are now back in pristine condition.\n```\n\nForcing deletion works the same way: if you hard delete a record, its dependent records will also be hard deleted.\n\n## Can I use default scopes?\n\n```ruby\ndefault_scope where(:deleted_at =\u003e nil)\n```\n\nIf you use such a default scope, you will need to simulate the `deleted` scope with a method\n\n```ruby\ndef self.deleted\n  self.unscoped.where('deleted_at IS NOT NULL')\nend\n```\n\n## Is Everything Automated?\n\nYes. You don't have to change ANY of your code to get permanent archiving of all your data with this gem.\nWhen you call `destroy` on any record  (or `destroy_all` on a class or association) your records will\nall have a deleted_at timestamp set on them.\n\n## Upgrading from 3.x\n\nThe behaviour of the `destroy` method has been updated so that it now returns\n`false` when halted by a before_destroy callback. This is in line with behaviour\nof ActiveRecord. For more information see\n[#47](https://github.com/JackDanger/permanent_records/issues/47).\n\n## Productionizing\n\nIf you operate a system where destroying or reviving a record takes more\nthan about 3 seconds then you'll want to customize\n`PermanentRecords.dependent_record_window = 10.seconds` or some other\nvalue that works for you.\n\nPatches welcome, forks celebrated.\n\nCopyright 2015 Jack Danger Canty @ [https://jdanger.com](https://jdanger.com) released under the MIT license\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJackDanger%2Fpermanent_records","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJackDanger%2Fpermanent_records","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJackDanger%2Fpermanent_records/lists"}