state_machine 0.6.3 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.rdoc +31 -1
- data/README.rdoc +33 -21
- data/Rakefile +2 -2
- data/examples/merb-rest/controller.rb +51 -0
- data/examples/merb-rest/model.rb +28 -0
- data/examples/merb-rest/view_edit.html.erb +24 -0
- data/examples/merb-rest/view_index.html.erb +23 -0
- data/examples/merb-rest/view_new.html.erb +13 -0
- data/examples/merb-rest/view_show.html.erb +17 -0
- data/examples/rails-rest/controller.rb +43 -0
- data/examples/rails-rest/migration.rb +11 -0
- data/examples/rails-rest/model.rb +23 -0
- data/examples/rails-rest/view_edit.html.erb +25 -0
- data/examples/rails-rest/view_index.html.erb +23 -0
- data/examples/rails-rest/view_new.html.erb +14 -0
- data/examples/rails-rest/view_show.html.erb +17 -0
- data/lib/state_machine/assertions.rb +2 -2
- data/lib/state_machine/callback.rb +14 -8
- data/lib/state_machine/condition_proxy.rb +3 -3
- data/lib/state_machine/event.rb +19 -21
- data/lib/state_machine/event_collection.rb +114 -0
- data/lib/state_machine/extensions.rb +127 -11
- data/lib/state_machine/guard.rb +1 -1
- data/lib/state_machine/integrations/active_record/locale.rb +2 -1
- data/lib/state_machine/integrations/active_record.rb +117 -39
- data/lib/state_machine/integrations/data_mapper/observer.rb +20 -64
- data/lib/state_machine/integrations/data_mapper.rb +71 -26
- data/lib/state_machine/integrations/sequel.rb +69 -21
- data/lib/state_machine/machine.rb +267 -139
- data/lib/state_machine/machine_collection.rb +145 -0
- data/lib/state_machine/matcher.rb +2 -2
- data/lib/state_machine/node_collection.rb +9 -4
- data/lib/state_machine/state.rb +22 -32
- data/lib/state_machine/state_collection.rb +66 -17
- data/lib/state_machine/transition.rb +259 -28
- data/lib/state_machine.rb +121 -56
- data/tasks/state_machine.rake +1 -0
- data/tasks/state_machine.rb +26 -0
- data/test/active_record.log +116877 -0
- data/test/functional/state_machine_test.rb +118 -12
- data/test/sequel.log +28542 -0
- data/test/unit/callback_test.rb +46 -1
- data/test/unit/condition_proxy_test.rb +55 -28
- data/test/unit/event_collection_test.rb +228 -0
- data/test/unit/event_test.rb +51 -46
- data/test/unit/integrations/active_record_test.rb +128 -70
- data/test/unit/integrations/data_mapper_test.rb +150 -58
- data/test/unit/integrations/sequel_test.rb +63 -6
- data/test/unit/invalid_event_test.rb +7 -0
- data/test/unit/machine_collection_test.rb +678 -0
- data/test/unit/machine_test.rb +198 -91
- data/test/unit/node_collection_test.rb +33 -30
- data/test/unit/state_collection_test.rb +112 -5
- data/test/unit/state_test.rb +23 -3
- data/test/unit/transition_test.rb +750 -89
- metadata +28 -3
    
        data/CHANGELOG.rdoc
    CHANGED
    
    | @@ -1,6 +1,36 @@ | |
| 1 1 | 
             
            == master
         | 
| 2 2 |  | 
| 3 | 
            -
            == 0. | 
| 3 | 
            +
            == 0.7.0 / 2009-04-03
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Add #{attribute}_event for automatically firing events when the object's action is called
         | 
| 6 | 
            +
            * Make it easier to override state-driven behaviors
         | 
| 7 | 
            +
            * Rollback state changes when the action fails during transitions
         | 
| 8 | 
            +
            * Use :messages instead of :invalid_message for customizing validation errors
         | 
| 9 | 
            +
            * Use more human-readable validation errors
         | 
| 10 | 
            +
            * Add support for more ActiveRecord observer hooks
         | 
| 11 | 
            +
            * Add support for targeting multiple specific state machines in DataMapper observer hooks
         | 
| 12 | 
            +
            * Don't pass the result of the action as an argument to callbacks (access via Transition#result)
         | 
| 13 | 
            +
            * Fix incorrect results being used when running transitions in parallel
         | 
| 14 | 
            +
            * Fix transition args not being set when run in parallel
         | 
| 15 | 
            +
            * Allow callback terminators to be set on an application-wide basis
         | 
| 16 | 
            +
            * Only catch :halt during before / after transition callbacks
         | 
| 17 | 
            +
            * Fix ActiveRecord predicates being overwritten if they're already defined in the class
         | 
| 18 | 
            +
            * Allow machine options to be set on an integration-wide basis
         | 
| 19 | 
            +
            * Turn transactions off by default in DataMapper integrations
         | 
| 20 | 
            +
            * Add support for configuring the use of transactions
         | 
| 21 | 
            +
            * Simplify reading/writing of attributes
         | 
| 22 | 
            +
            * Simplify access to state machines via #state_machine(:attribute) without generating dupes
         | 
| 23 | 
            +
            * Fix assumptions that dm-validations is always available in DataMapper integration
         | 
| 24 | 
            +
            * Automatically define DataMapper properties for machine attributes if they don't exist
         | 
| 25 | 
            +
            * Add Transition#qualified_event, #qualified_from_name, and #qualified_to_name
         | 
| 26 | 
            +
            * Add #fire_events / #fire_events! for running events on multiple state machines in parallel
         | 
| 27 | 
            +
            * Rename next_#{event}_transition to #{event}_transition
         | 
| 28 | 
            +
            * Add #{attribute}_transitions for getting the list of transitions that can be run on an object
         | 
| 29 | 
            +
            * Add #{attribute}_events for getting the list of events that can be fired on an object
         | 
| 30 | 
            +
            * Use generated non-bang event when running bang version so that overriding one affects the other
         | 
| 31 | 
            +
            * Provide access to arguments passed into an event from transition callbacks via Transition#args
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            == 0.6.3 / 2009-03-10
         | 
| 4 34 |  | 
| 5 35 | 
             
            * Add support for customizing the graph's orientation
         | 
| 6 36 | 
             
            * Use the standard visualizations for initial (open arrow) and final (double circle) states
         | 
    
        data/README.rdoc
    CHANGED
    
    | @@ -45,6 +45,8 @@ Some brief, high-level features include: | |
| 45 45 | 
             
            * State-driven instance / class behavior
         | 
| 46 46 | 
             
            * State values of any data type
         | 
| 47 47 | 
             
            * Dynamically-generated state values
         | 
| 48 | 
            +
            * Event parallelization
         | 
| 49 | 
            +
            * Attribute-based event transitions
         | 
| 48 50 | 
             
            * Inheritance
         | 
| 49 51 | 
             
            * Internationalization
         | 
| 50 52 | 
             
            * GraphViz visualization creator
         | 
| @@ -63,6 +65,7 @@ Below is an example of many of the features offered by this plugin, including: | |
| 63 65 | 
             
            * Conditional transitions
         | 
| 64 66 | 
             
            * State-driven instance behavior
         | 
| 65 67 | 
             
            * Customized state values
         | 
| 68 | 
            +
            * Parallel events
         | 
| 66 69 |  | 
| 67 70 | 
             
            Class definition:
         | 
| 68 71 |  | 
| @@ -125,17 +128,17 @@ Class definition: | |
| 125 128 | 
             
                  end
         | 
| 126 129 | 
             
                end
         | 
| 127 130 |  | 
| 128 | 
            -
                state_machine : | 
| 129 | 
            -
                  event : | 
| 130 | 
            -
                    transition all => : | 
| 131 | 
            +
                state_machine :alarm_state, :initial => :active, :namespace => 'alarm' do
         | 
| 132 | 
            +
                  event :enable do
         | 
| 133 | 
            +
                    transition all => :active
         | 
| 131 134 | 
             
                  end
         | 
| 132 135 |  | 
| 133 | 
            -
                  event : | 
| 134 | 
            -
                    transition all => : | 
| 136 | 
            +
                  event :disable do
         | 
| 137 | 
            +
                    transition all => :off
         | 
| 135 138 | 
             
                  end
         | 
| 136 139 |  | 
| 137 | 
            -
                  state : | 
| 138 | 
            -
                  state : | 
| 140 | 
            +
                  state :active, :value => 1
         | 
| 141 | 
            +
                  state :off, :value => 0
         | 
| 139 142 | 
             
                end
         | 
| 140 143 |  | 
| 141 144 | 
             
                def initialize
         | 
| @@ -168,7 +171,9 @@ like so: | |
| 168 171 | 
             
              vehicle.state_name              # => :parked
         | 
| 169 172 | 
             
              vehicle.parked?                 # => true
         | 
| 170 173 | 
             
              vehicle.can_ignite?             # => true
         | 
| 171 | 
            -
              vehicle. | 
| 174 | 
            +
              vehicle.ignite_transition       # => #<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>
         | 
| 175 | 
            +
              vehicle.state_events            # => [:ignite]
         | 
| 176 | 
            +
              vehicle.state_transitions       # => [#<StateMachine::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>]
         | 
| 172 177 | 
             
              vehicle.speed                   # => 0
         | 
| 173 178 |  | 
| 174 179 | 
             
              vehicle.ignite                  # => true
         | 
| @@ -189,21 +194,28 @@ like so: | |
| 189 194 | 
             
              vehicle.park!                   # => StateMachine::InvalidTransition: Cannot transition state via :park from :second_gear
         | 
| 190 195 |  | 
| 191 196 | 
             
              # Generic state predicates can raise exceptions if the value does not exist
         | 
| 192 | 
            -
              vehicle.state?(:parked)         # =>  | 
| 193 | 
            -
              vehicle.state?(:invalid)        # =>  | 
| 197 | 
            +
              vehicle.state?(:parked)         # => false
         | 
| 198 | 
            +
              vehicle.state?(:invalid)        # => IndexError: :invalid is an invalid name
         | 
| 194 199 |  | 
| 195 200 | 
             
              # Namespaced machines have uniquely-generated methods
         | 
| 196 | 
            -
              vehicle. | 
| 197 | 
            -
              vehicle. | 
| 201 | 
            +
              vehicle.alarm_state             # => 1
         | 
| 202 | 
            +
              vehicle.alarm_state_name        # => :active
         | 
| 198 203 |  | 
| 199 | 
            -
              vehicle. | 
| 200 | 
            -
              vehicle. | 
| 201 | 
            -
              vehicle. | 
| 202 | 
            -
              vehicle. | 
| 203 | 
            -
              vehicle. | 
| 204 | 
            +
              vehicle.can_disable_alarm?      # => true
         | 
| 205 | 
            +
              vehicle.disable_alarm           # => true
         | 
| 206 | 
            +
              vehicle.alarm_state             # => 0
         | 
| 207 | 
            +
              vehicle.alarm_state_name        # => :off
         | 
| 208 | 
            +
              vehicle.can_enable_alarm?       # => true
         | 
| 204 209 |  | 
| 205 | 
            -
              vehicle. | 
| 206 | 
            -
              vehicle. | 
| 210 | 
            +
              vehicle.alarm_off?              # => true
         | 
| 211 | 
            +
              vehicle.alarm_active?           # => false
         | 
| 212 | 
            +
              
         | 
| 213 | 
            +
              # Events can be fired in parallel
         | 
| 214 | 
            +
              vehicle.fire_events(:shift_down, :enable_alarm) # => true
         | 
| 215 | 
            +
              vehicle.state_name                              # => :first_gear
         | 
| 216 | 
            +
              vehicle.alarm_state_name                        # => :active
         | 
| 217 | 
            +
              
         | 
| 218 | 
            +
              vehicle.fire_events!(:ignite, :enable_alarm)    # => StateMachine::InvalidTransition: Cannot run events in parallel: ignite, enable_alarm
         | 
| 207 219 |  | 
| 208 220 | 
             
            *Note* the comment made on the +initialize+ method in the class.  In order for
         | 
| 209 221 | 
             
            state machine attributes to be properly initialized, <tt>super()</tt> must be called.
         | 
| @@ -307,8 +319,8 @@ callbacks, validation errors, and observers.  For example, | |
| 307 319 | 
             
                end
         | 
| 308 320 |  | 
| 309 321 | 
             
                # Generic transition callback *before* the transition is performed
         | 
| 310 | 
            -
                after_transition do |transition | 
| 311 | 
            -
                  Audit.log(self, transition)  | 
| 322 | 
            +
                after_transition do |transition|
         | 
| 323 | 
            +
                  Audit.log(self, transition) # self is the record
         | 
| 312 324 | 
             
                end
         | 
| 313 325 | 
             
              end
         | 
| 314 326 |  | 
    
        data/Rakefile
    CHANGED
    
    | @@ -5,11 +5,11 @@ require 'rake/contrib/sshpublisher' | |
| 5 5 |  | 
| 6 6 | 
             
            spec = Gem::Specification.new do |s|
         | 
| 7 7 | 
             
              s.name              = 'state_machine'
         | 
| 8 | 
            -
              s.version           = '0. | 
| 8 | 
            +
              s.version           = '0.7.0'
         | 
| 9 9 | 
             
              s.platform          = Gem::Platform::RUBY
         | 
| 10 10 | 
             
              s.summary           = 'Adds support for creating state machines for attributes on any Ruby class'
         | 
| 11 11 |  | 
| 12 | 
            -
              s.files             = FileList['{examples,lib,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
         | 
| 12 | 
            +
              s.files             = FileList['{examples,lib,tasks,test}/**/*'] + %w(CHANGELOG.rdoc init.rb LICENSE Rakefile README.rdoc) - FileList['test/app_root/{log,log/*,script,script/*}']
         | 
| 13 13 | 
             
              s.require_path      = 'lib'
         | 
| 14 14 | 
             
              s.has_rdoc          = true
         | 
| 15 15 | 
             
              s.test_files        = Dir['test/**/*_test.rb']
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            class Users < Application
         | 
| 2 | 
            +
              # GET /users
         | 
| 3 | 
            +
              def index
         | 
| 4 | 
            +
                @users = User.all
         | 
| 5 | 
            +
                display @users
         | 
| 6 | 
            +
              end
         | 
| 7 | 
            +
              
         | 
| 8 | 
            +
              # GET /users/1
         | 
| 9 | 
            +
              def show(id)
         | 
| 10 | 
            +
                @user = User.get(id)
         | 
| 11 | 
            +
                raise NotFound unless @user
         | 
| 12 | 
            +
                display @user
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              # GET /users/new
         | 
| 16 | 
            +
              def new
         | 
| 17 | 
            +
                only_provides :html
         | 
| 18 | 
            +
                @user = User.new
         | 
| 19 | 
            +
                display @user
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              # GET /users/1/edit
         | 
| 23 | 
            +
              def edit(id)
         | 
| 24 | 
            +
                only_provides :html
         | 
| 25 | 
            +
                @user = User.get(id)
         | 
| 26 | 
            +
                raise NotFound unless @user
         | 
| 27 | 
            +
                display @user
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
              
         | 
| 30 | 
            +
              # POST /users
         | 
| 31 | 
            +
              def create(user)
         | 
| 32 | 
            +
                @user = User.new(user)
         | 
| 33 | 
            +
                if @user.save
         | 
| 34 | 
            +
                  redirect resource(@user), :message => {:notice => "User was successfully created"}
         | 
| 35 | 
            +
                else
         | 
| 36 | 
            +
                  message[:error] = "User failed to be created"
         | 
| 37 | 
            +
                  render :new
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              # PUT /users/1
         | 
| 42 | 
            +
              def update(id, user)
         | 
| 43 | 
            +
                @user = User.get(id)
         | 
| 44 | 
            +
                raise NotFound unless @user
         | 
| 45 | 
            +
                if @user.update_attributes(user)
         | 
| 46 | 
            +
                   redirect resource(@user)
         | 
| 47 | 
            +
                else
         | 
| 48 | 
            +
                  display @user, :edit
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         | 
| @@ -0,0 +1,28 @@ | |
| 1 | 
            +
            class User
         | 
| 2 | 
            +
              include DataMapper::Resource
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              property :id, Serial
         | 
| 5 | 
            +
              property :name, String
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              validates_present :name, :state, :access_state
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              state_machine :initial => :unregistered do
         | 
| 10 | 
            +
                event :register do
         | 
| 11 | 
            +
                  transition :unregistered => :registered
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                event :unregister do
         | 
| 15 | 
            +
                  transition :registered => :unregistered
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              state_machine :access_state, :initial => :enabled do
         | 
| 20 | 
            +
                event :enable do
         | 
| 21 | 
            +
                  transition all => :enabled
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
                
         | 
| 24 | 
            +
                event :disable do
         | 
| 25 | 
            +
                  transition all => :disabled
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            <h1>Editing User</h1>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <%= form_for @user, :action => resource(@user) do %>
         | 
| 4 | 
            +
              <%= error_messages %>
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              <p>
         | 
| 7 | 
            +
                <%= text_field :name, :label => 'Name' %>
         | 
| 8 | 
            +
              </p>
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              <p>
         | 
| 11 | 
            +
                <%= label :state %><br />
         | 
| 12 | 
            +
                <%= select :state_event, :selected => @user.state_event.to_s, :collection => @user.state_transitions, :value_method => :event, :text_method => :to_name, :prompt => @user.state_name.to_s %>
         | 
| 13 | 
            +
              </p>
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              <p>
         | 
| 16 | 
            +
                <%= label :access_state %><br />
         | 
| 17 | 
            +
                <%= select :access_state_event, :selected => @user.access_state_event.to_s, :collection => @user.access_state_transitions, :value_method => :event, :text_method => :event, :prompt => "don't change" %>
         | 
| 18 | 
            +
              </p>
         | 
| 19 | 
            +
              
         | 
| 20 | 
            +
              <p><%= submit 'Update' %></p>
         | 
| 21 | 
            +
            <% end =%>
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            <%= link_to 'Show', resource(@user) %> |
         | 
| 24 | 
            +
            <%= link_to 'Back', resource(:users) %>
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            <h1>Listing Users</h1>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <table>
         | 
| 4 | 
            +
              <tr>
         | 
| 5 | 
            +
                <th>Name</th>
         | 
| 6 | 
            +
                <th>State</th>
         | 
| 7 | 
            +
                <th>Access State</th>
         | 
| 8 | 
            +
              </tr>
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
            <% @users.each do |user| %>
         | 
| 11 | 
            +
              <tr>
         | 
| 12 | 
            +
                <td><%=h user.name %></td>
         | 
| 13 | 
            +
                <td><%=h user.state %></td>
         | 
| 14 | 
            +
                <td><%=h user.access_state %></td>
         | 
| 15 | 
            +
                <td><%= link_to 'Show', resource(user) %></td>
         | 
| 16 | 
            +
                <td><%= link_to 'Edit', resource(user, :edit) %></td>
         | 
| 17 | 
            +
              </tr>
         | 
| 18 | 
            +
            <% end %>
         | 
| 19 | 
            +
            </table>
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            <br />
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            <%= link_to 'New User', resource(:users, :new) %>
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            <p>
         | 
| 2 | 
            +
              <b>Name:</b>
         | 
| 3 | 
            +
              <%=h @user.name %>
         | 
| 4 | 
            +
            </p>
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            <p>
         | 
| 7 | 
            +
              <b>State:</b>
         | 
| 8 | 
            +
              <%=h @user.state %>
         | 
| 9 | 
            +
            </p>
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            <p>
         | 
| 12 | 
            +
              <b>Access State:</b>
         | 
| 13 | 
            +
              <%=h @user.access_state %>
         | 
| 14 | 
            +
            </p>
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            <%= link_to 'Edit', resource(@user, :edit) %> |
         | 
| 17 | 
            +
            <%= link_to 'Back', resource(:users) %>
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            class UsersController < ApplicationController
         | 
| 2 | 
            +
              # GET /users
         | 
| 3 | 
            +
              def index
         | 
| 4 | 
            +
                @users = User.all
         | 
| 5 | 
            +
              end
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              # GET /users/1
         | 
| 8 | 
            +
              def show
         | 
| 9 | 
            +
                @user = User.find(params[:id])
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              # GET /users/new
         | 
| 13 | 
            +
              def new
         | 
| 14 | 
            +
                @user = User.new
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
              
         | 
| 17 | 
            +
              # GET /users/1/edit
         | 
| 18 | 
            +
              def edit
         | 
| 19 | 
            +
                @user = User.find(params[:id])
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
              
         | 
| 22 | 
            +
              # POST /users
         | 
| 23 | 
            +
              def create
         | 
| 24 | 
            +
                @user = User.new(params[:user])
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                if @user.save
         | 
| 27 | 
            +
                  redirect_to(@user)
         | 
| 28 | 
            +
                else
         | 
| 29 | 
            +
                  render :action => 'new'
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
              
         | 
| 33 | 
            +
              # PUT /users/1
         | 
| 34 | 
            +
              def update
         | 
| 35 | 
            +
                @user = User.find(params[:id])
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                if @user.update_attributes(params[:user])
         | 
| 38 | 
            +
                  redirect_to(@user)
         | 
| 39 | 
            +
                else
         | 
| 40 | 
            +
                  render :action => 'edit'
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            class User < ActiveRecord::Base
         | 
| 2 | 
            +
              validates_presence_of :name, :state, :access_state
         | 
| 3 | 
            +
              
         | 
| 4 | 
            +
              state_machine :initial => :unregistered do
         | 
| 5 | 
            +
                event :register do
         | 
| 6 | 
            +
                  transition :unregistered => :registered
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                event :unregister do
         | 
| 10 | 
            +
                  transition :registered => :unregistered
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
              state_machine :access_state, :initial => :enabled do
         | 
| 15 | 
            +
                event :enable do
         | 
| 16 | 
            +
                  transition all => :enabled
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                event :disable do
         | 
| 20 | 
            +
                  transition all => :disabled
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,25 @@ | |
| 1 | 
            +
            <h1>Editing User</h1>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <% form_for(@user) do |f| %>
         | 
| 4 | 
            +
              <%= f.error_messages %>
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              <p>
         | 
| 7 | 
            +
                <%= f.label :name %><br />
         | 
| 8 | 
            +
                <%= f.text_field :name %>
         | 
| 9 | 
            +
              </p>
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
              <p>
         | 
| 12 | 
            +
                <%= f.label :state %><br />
         | 
| 13 | 
            +
                <%= f.collection_select :state_event, @user.state_transitions, :event, :to_name, :include_blank => @user.state_name.to_s %>
         | 
| 14 | 
            +
              </p>
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              <p>
         | 
| 17 | 
            +
                <%= f.label :access_state %><br />
         | 
| 18 | 
            +
                <%= f.collection_select :access_state_event, @user.access_state_transitions, :event, :event, :include_blank => "don't change" %>
         | 
| 19 | 
            +
              </p>
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              <p><%= f.submit 'Update' %></p>
         | 
| 22 | 
            +
            <% end %>
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            <%= link_to 'Show', @user %> |
         | 
| 25 | 
            +
            <%= link_to 'Back', users_path %>
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            <h1>Listing Users</h1>
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            <table>
         | 
| 4 | 
            +
              <tr>
         | 
| 5 | 
            +
                <th>Name</th>
         | 
| 6 | 
            +
                <th>State</th>
         | 
| 7 | 
            +
                <th>Access State</th>
         | 
| 8 | 
            +
              </tr>
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
            <% @users.each do |user| %>
         | 
| 11 | 
            +
              <tr>
         | 
| 12 | 
            +
                <td><%=h user.name %></td>
         | 
| 13 | 
            +
                <td><%=h user.state %></td>
         | 
| 14 | 
            +
                <td><%=h user.access_state %></td>
         | 
| 15 | 
            +
                <td><%= link_to 'Show', user %></td>
         | 
| 16 | 
            +
                <td><%= link_to 'Edit', edit_user_path(user) %></td>
         | 
| 17 | 
            +
              </tr>
         | 
| 18 | 
            +
            <% end %>
         | 
| 19 | 
            +
            </table>
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            <br />
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            <%= link_to 'New User', new_user_path %>
         |