-
Notifications
You must be signed in to change notification settings - Fork 0
/
params.json
1 lines (1 loc) · 10.9 KB
/
params.json
1
{"name":"aasm","tagline":"Ruby state machines","body":"# AASM - Ruby state machines [![Build Status](https://secure.travis-ci.org/aasm/aasm.png)](http://travis-ci.org/aasm/aasm) [![Code Climate](https://codeclimate.com/github/aasm/aasm.png)](https://codeclimate.com/github/aasm/aasm) [![Coverage Status](https://coveralls.io/repos/aasm/aasm/badge.png?branch=master)](https://coveralls.io/r/aasm/aasm)\r\n\r\nThis package contains AASM, a library for adding finite state machines to Ruby classes.\r\n\r\nAASM started as the *acts_as_state_machine* plugin but has evolved into a more generic library\r\nthat no longer targets only ActiveRecord models. It currently provides adapters for\r\n[ActiveRecord](http://api.rubyonrails.org/classes/ActiveRecord/Base.html) and\r\n[Mongoid](http://mongoid.org/), but it can be used for any Ruby class, no matter what\r\nparent class it has (if any).\r\n\r\n## Usage\r\n\r\nAdding a state machine is as simple as including the AASM module and start defining\r\n**states** and **events** together with their **transitions**:\r\n\r\n```ruby\r\nclass Job\r\n include AASM\r\n\r\n aasm do\r\n state :sleeping, :initial => true\r\n state :running\r\n state :cleaning\r\n\r\n event :run do\r\n transitions :from => :sleeping, :to => :running\r\n end\r\n\r\n event :clean do\r\n transitions :from => :running, :to => :cleaning\r\n end\r\n\r\n event :sleep do\r\n transitions :from => [:running, :cleaning], :to => :sleeping\r\n end\r\n end\r\n\r\nend\r\n```\r\n\r\nThis provides you with a couple of public methods for instances of the class `Job`:\r\n\r\n```ruby\r\njob = Job.new\r\njob.sleeping? # => true\r\njob.may_run? # => true\r\njob.run\r\njob.running? # => true\r\njob.sleeping? # => false\r\njob.may_run? # => false\r\njob.run # => raises AASM::InvalidTransition\r\n```\r\n\r\nIf you don't like exceptions and prefer a simple `true` or `false` as response, tell\r\nAASM not to be *whiny*:\r\n\r\n```ruby\r\nclass Job\r\n ...\r\n aasm :whiny_transitions => false do\r\n ...\r\n end\r\nend\r\n\r\njob.running? # => true\r\njob.may_run? # => false\r\njob.run # => false\r\n```\r\n\r\n### Callbacks\r\n\r\nYou can define a number of callbacks for your transitions. These methods will be\r\ncalled, when certain criteria are met, like entering a particular state:\r\n\r\n```ruby\r\nclass Job\r\n include AASM\r\n\r\n aasm do\r\n state :sleeping, :initial => true, :before_enter => :do_something\r\n state :running\r\n\r\n event :run, :after => Proc.new { |user| notify_somebody(user) } do\r\n transitions :from => :sleeping, :to => :running, :on_transition => Proc.new {|obj, *args| obj.set_process(*args) }\r\n end\r\n\r\n event :sleep do\r\n after do\r\n ...\r\n end\r\n error do |e|\r\n ...\r\n end\r\n transitions :from => :running, :to => :sleeping\r\n end\r\n end\r\n\r\n def set_process(name)\r\n ...\r\n end\r\n\r\n def do_something\r\n ...\r\n end\r\n\r\n def notify_somebody(user)\r\n ...\r\n end\r\n\r\nend\r\n```\r\n\r\nIn this case `do_something` is called before actually entering the state `sleeping`,\r\nwhile `notify_somebody` is called after the transition `run` (from `sleeping` to `running`)\r\nis finished.\r\n\r\nHere you can see a list of all possible callbacks, together with their order of calling:\r\n\r\n```ruby\r\n event:before\r\n previous_state:before_exit\r\n new_state:before_enter\r\n ...update state...\r\n previous_state:after_exit\r\n new_state:after_enter\r\n event:after\r\n```\r\n\r\nAlso, you can pass parameters to events:\r\n\r\n```ruby\r\n job = Job.new\r\n job.run(:running, :defragmentation)\r\n```\r\n\r\nIn this case the `set_process` would be called with `:defagmentation` argument.\r\n\r\nIn case of an error during the event processing the error is rescued and passed to `:error`\r\ncallback, which can handle it or re-raise it for further propagation.\r\n\r\n### Guards\r\n\r\nLet's assume you want to allow particular transitions only if a defined condition is\r\ngiven. For this you can set up a guard per transition, which will run before actually\r\nrunning the transition. If the guard returns `false` the transition will be\r\ndenied (raising `AASM::InvalidTransition` or returning `false` itself):\r\n\r\n```ruby\r\nclass Job\r\n include AASM\r\n\r\n aasm do\r\n state :sleeping, :initial => true\r\n state :running\r\n state :cleaning\r\n\r\n event :run do\r\n transitions :from => :sleeping, :to => :running\r\n end\r\n\r\n event :clean do\r\n transitions :from => :running, :to => :cleaning\r\n end\r\n\r\n event :sleep do\r\n transitions :from => :running, :to => :sleeping, :guard => :cleaning_needed?\r\n end\r\n end\r\n\r\n def cleaning_needed?\r\n false\r\n end\r\n\r\nend\r\n\r\njob = Job.new\r\njob.run\r\njob.may_sleep? # => false\r\njob.sleep # => raises AASM::InvalidTransition\r\n```\r\n\r\n\r\n### ActiveRecord\r\n\r\nAASM comes with support for ActiveRecord and allows automatical persisting of the object's\r\nstate in the database.\r\n\r\n```ruby\r\nclass Job < ActiveRecord::Base\r\n include AASM\r\n\r\n aasm do # default column: aasm_state\r\n state :sleeping, :initial => true\r\n state :running\r\n\r\n event :run do\r\n transitions :from => :sleeping, :to => :running\r\n end\r\n\r\n event :sleep do\r\n transitions :from => :running, :to => :sleeping\r\n end\r\n end\r\n\r\nend\r\n```\r\n\r\nYou can tell AASM to auto-save the object or leave it unsaved\r\n\r\n```ruby\r\njob = Job.new\r\njob.run # not saved\r\njob.run! # saved\r\n```\r\n\r\nSaving includes running all validations on the `Job` class. If you want make sure\r\nthe state gets saved without running validations (and thereby maybe persisting an\r\ninvalid object state), simply tell AASM to skip the validations:\r\n\r\n```ruby\r\nclass Job < ActiveRecord::Base\r\n include AASM\r\n\r\n aasm :skip_validation_on_save => true do\r\n state :sleeping, :initial => true\r\n state :running\r\n\r\n event :run do\r\n transitions :from => :sleeping, :to => :running\r\n end\r\n\r\n event :sleep do\r\n transitions :from => :running, :to => :sleeping\r\n end\r\n end\r\n\r\nend\r\n```\r\n\r\n### Automatic Scopes\r\n\r\nAASM will automatically create scope methods for each state in the model.\r\n\r\n```ruby\r\nclass Job < ActiveRecord::Base\r\n include AASM\r\n\r\n aasm do\r\n state :sleeping, :initial => true\r\n state :running\r\n state :cleaning\r\n end\r\n\r\n def sleeping\r\n \"This method name is in already use\"\r\n end\r\nend\r\n```\r\n\r\n```ruby\r\nclass JobsController < ApplicationController\r\n def index\r\n @running_jobs = jobs.running\r\n @recent_cleaning_jobs = jobs.cleaning.where('created_at >= ?', 3.days.ago)\r\n\r\n # @sleeping_jobs = jobs.sleeping #=> \"This method name is in already use\"\r\n end\r\nend\r\n```\r\n\r\nIf you don't need scopes (or simply don't want them), disable their creation when\r\ndefining the `AASM` states, like this:\r\n\r\n```ruby\r\nclass Job < ActiveRecord::Base\r\n include AASM\r\n\r\n aasm :create_scopes => false do\r\n state :sleeping, :initial => true\r\n state :running\r\n state :cleaning\r\n end\r\nend\r\n```\r\n\r\n\r\n### Transaction support\r\n\r\nSince version *3.0.13* AASM supports ActiveRecord transactions. So whenever a transition\r\ncallback or the state update fails, all changes to any database record are rolled back.\r\n\r\n### Column name & migration\r\n\r\nAs a default AASM uses the column `aasm_state` to store the states. You can override\r\nthis by defining your favorite column name, using `:column` like this:\r\n\r\n```ruby\r\nclass Job < ActiveRecord::Base\r\n include AASM\r\n\r\n aasm :column => 'my_state' do\r\n ...\r\n end\r\n\r\nend\r\n```\r\n\r\nWhatever column name is used, make sure to add a migration to provide this column\r\n(of type `string`):\r\n\r\n```ruby\r\nclass AddJobState < ActiveRecord::Migration\r\n def self.up\r\n add_column :jobs, :aasm_state, :string\r\n end\r\n\r\n def self.down\r\n remove_column :jobs, :aasm_state\r\n end\r\nend\r\n```\r\n\r\n### <a id=\"inspection\">Inspection\r\n\r\nAASM supports a couple of methods to find out which states or events are provided or permissible.\r\n\r\nGiven the `Job` class from above:\r\n\r\n```ruby\r\njob = Job.new\r\n\r\njob.aasm.states\r\n=> [:sleeping, :running, :cleaning]\r\n\r\njob.aasm.states(:permissible => true)\r\n=> [:running]\r\njob.run\r\njob.aasm.states(:permissible => true)\r\n=> [:cleaning, :sleeping]\r\n\r\njob.aasm.events\r\n=> [:run, :clean, :sleep]\r\n```\r\n\r\n\r\n\r\n## <a id=\"installation\">Installation ##\r\n\r\n### Manually from RubyGems.org ###\r\n\r\n```sh\r\n% gem install aasm\r\n```\r\n\r\n### Or if you are using Bundler ###\r\n\r\n```ruby\r\n# Gemfile\r\ngem 'aasm'\r\n```\r\n\r\n### Building your own gems ###\r\n\r\n```sh\r\n% rake build\r\n% sudo gem install pkg/aasm-x.y.z.gem\r\n```\r\n\r\n## Latest changes ##\r\n\r\nLook at the [CHANGELOG](https://github.com/aasm/aasm/blob/master/CHANGELOG.md) for details.\r\n\r\n## Questions? ##\r\n\r\nFeel free to\r\n\r\n* [create an issue on GitHub](https://github.com/aasm/aasm/issues)\r\n* [ask a question on StackOverflow](http://stackoverflow.com) (tag with `aasm`)\r\n* send us a tweet [@aasm](http://twitter.com/aasm)\r\n\r\n## Authors ##\r\n\r\n* [Scott Barron](https://github.com/rubyist)\r\n* [Travis Tilley](https://github.com/ttilley)\r\n* [Thorsten Böttger](http://github.com/alto)\r\n\r\n\r\n## Warranty ##\r\n\r\nThis software is provided \"as is\" and without any express or\r\nimplied warranties, including, without limitation, the implied\r\nwarranties of merchantibility and fitness for a particular\r\npurpose.\r\n\r\n## License ##\r\n\r\nCopyright (c) 2006-2012 Scott Barron\r\n\r\nPermission is hereby granted, free of charge, to any person obtaining\r\na copy of this software and associated documentation files (the\r\n\"Software\"), to deal in the Software without restriction, including\r\nwithout limitation the rights to use, copy, modify, merge, publish,\r\ndistribute, sublicense, and/or sell copies of the Software, and to\r\npermit persons to whom the Software is furnished to do so, subject to\r\nthe following conditions:\r\n\r\nThe above copyright notice and this permission notice shall be\r\nincluded in all copies or substantial portions of the Software.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\r\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."}