{"id":18510790,"url":"https://github.com/envato/two-states","last_synced_at":"2025-05-14T11:19:39.889Z","repository":{"id":6381229,"uuid":"7618826","full_name":"envato/two-states","owner":"envato","description":null,"archived":false,"fork":false,"pushed_at":"2023-03-15T23:57:28.000Z","size":14,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-05-14T11:19:08.653Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/envato.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"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":"2013-01-15T04:55:07.000Z","updated_at":"2021-11-28T01:15:32.000Z","dependencies_parsed_at":"2024-11-06T15:42:15.844Z","dependency_job_id":null,"html_url":"https://github.com/envato/two-states","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envato%2Ftwo-states","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envato%2Ftwo-states/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envato%2Ftwo-states/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/envato%2Ftwo-states/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/envato","download_url":"https://codeload.github.com/envato/two-states/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254129636,"owners_count":22019632,"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-11-06T15:25:09.718Z","updated_at":"2025-05-14T11:19:39.833Z","avatar_url":"https://github.com/envato.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# two-states\n============\n\nThis is a *very* simple state machine library for ActiveRecord projects. It is designed above all else to be as simple and explicit as possible, while still providing enough flexibility for many projects.\n\nThe current state of a record is kept in a database column; one record can have as many state machines as you deem useful.\n\nState machines are simply subclasses of StateMachine; each state is a subclass of StateMachine::State (though you can treat them pretty much as if they're symbols if you like). \n\nEvents and transitions are just methods, defined inside your state machine class, which change the state. It's up to you to decide under what conditions a state transfer will occur and whether to raise a TransitionError or silently ignore failures. You can specify guard conditions inside transition methods if you need them. If you want other features, you'll either find you're able to easily add them yourself, or you'll go elsewhere.\n\nThere are no explicit dependencies on ActiveRecord, so you could probably use this in non-ActiveRecord Ruby projects if you wanted to. Small parts of ActiveSupport are selectively required.\n\n```ruby\ngem 'two-states', git: 'git@github.com:davidlee/two-states.git'\n\nrequire 'state_machine'\n\nclass Document \u003c MockRecord\n  attr_accessor :name, :content, :published_at, :deleted_at\n\n  # \n  # This is the idiomatic way to attach a state machine to your record\n  # \n\n  def status\n    @status ||= Document::Workflow.new(self, :status)\n  end\n\n  #\n  # Define our state machine as an inner class; it doesn't have to be though.\n  #\n\n  class Workflow \u003c StateMachine\n    \n    # define subclasses of StateMachine::State for each possible state \n\n    define_states :draft, :published, :deleted\n\n    # any helper methods declared here are available from within our transition methods\n\n    def document\n      record\n    end\n\n    def can_publish?\n      current_state == :draft\n    end\n\n    #\n    # transitions - you could use delegate if you wanted to call these on the record itself\n    # these are just plain old methods that happen to call #current_state=\n\n    def publish!(time=Time.now)\n      # check any preconditions by raising exceptions (including current states)\n      raise TransitionError.new(\"#{current_state} can't be published\") unless can_publish?\n      raise ArgumentError.new(\"#{time.inspect} is not a Time\") unless time.is_a?(Time)\n\n      document.published_at = time\n      self.current_state = :published\n      # you might like to call #save! here if this is were an activerecord model\n      true\n    end\n\n    def delete!(time=Time.now)\n      # check preconditions\n      raise TransitionError.new(\"already deleted\") if current_state == :deleted\n      raise ArgumentError.new(\"#{time.inspect} is not a Time\") unless time.is_a?(Time)\n\n      document.deleted_at = time\n      self.current_state = :deleted\n      # you might like to call #save! here if this is were an activerecord model\n      true\n    end\n\n  end\nend\n```\n\n\n```\nTwo states \nWe want two states \nNorth and south \nTwo, two states \nForty million daggers ... \nTwo states \nWe want two states \nThere's no culture \nThere's no spies \nForty million daggers ...\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvato%2Ftwo-states","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenvato%2Ftwo-states","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenvato%2Ftwo-states/lists"}