27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

264 CHAPTER 10 Tracking state<br />

Good, now you’ve got a way to test this state message that should be appearing when a<br />

comment changes the state of the ticket. Now, you’d like to track the state the ticket<br />

was at before the comment as well as the state of the comment itself. To track this extra<br />

attribute, you’ll create another field on your comments table called previous_state<br />

_id. Before you save a comment, you’ll update this field to be the current state of the<br />

ticket. Let’s create a new migration to add the previous_state_id field to your<br />

comments table by running the following command:<br />

rails g migration add_previous_state_id_to_comments previous_state_id:integer<br />

Again, Rails is pretty smart here and will use the name of the migration to infer that<br />

you want to add a column called previous_state_id to a table called comments. You<br />

only have to tell it what the type of this field is by passing previous_state_id<br />

:integer to the migration.<br />

If you open up this migration now, you’ll see that it defines a change method<br />

which calls the add_column method inside it. You can see the entire migration shown<br />

in the following listing.<br />

Listing 10.19 db/migrate_[date]_add_previous_state_id_to_comments.rb<br />

class AddPreviousStateIdToComments < ActiveRecord::Migration<br />

def change<br />

add_column :comments, :previous_state_id, :integer<br />

end<br />

end<br />

It’s done this way because Rails knows how to roll back this migration easily. It’s a simple<br />

call to remove_column passing in the first two arguments in this method.<br />

You don’t need to do anything else to this migration other than run it. Do this now<br />

by running rake db:migrate and rake db:test:prepare. This field will be used for<br />

storing the previous state’s id so that you can then use it to show a state transition on a<br />

comment, as pictured in figure 10.11.<br />

With this little bit of information, users can see what comments<br />

changed the ticket’s state, which is helpful for determining what<br />

steps the ticket has gone through to wind up at this point.<br />

To use the previous_state_id field properly, you’re going to<br />

need to add another callback to save it.<br />

10.3.2 Another c-c-callback<br />

Figure 10.11<br />

A state transition<br />

To set this field before a comment is created, you use a before_create callback on the<br />

Comment model. A before_create callback is triggered—as the name suggests—<br />

before a record is created, but after the validations have been run. This means that this<br />

callback will only be triggered for valid objects that are about to be saved to the database<br />

for the first time.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!