27.02.2013 Views

Rails%203%20In%20Action

Rails%203%20In%20Action

Rails%203%20In%20Action

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

276 CHAPTER 10 Tracking state<br />

def make_default<br />

@state = State.find(params[:id])<br />

@state.default!<br />

flash[:notice] = "#{@state.name} is now the default state."<br />

redirect_to admin_states_path<br />

end<br />

Rather than putting the logic to change the selected state to the new default inside<br />

the controller, you place it in the model. To trigger a state to become the new default<br />

state, you call the default! method on it. It’s best practice to put code that performs<br />

functionality like this inside the model.<br />

This default! method can be defined in the State model, as shown in the following<br />

listing.<br />

def default!<br />

current_default_state = State.find_by_default(true)<br />

end<br />

Listing 10.26 app/controllers/admin/states_controller.rb<br />

Listing 10.27 app/models/state.rb<br />

self.default = true<br />

self.save!<br />

if current_default_state<br />

current_default_state.default = false<br />

current_default_state.save!<br />

end<br />

The find_by_default B method here is a dynamic finder method from Active<br />

Record. The find_by_default will either return the State object for the default<br />

state, or nil. If it doesn’t return nil C then you change its default state to false<br />

and save the record.<br />

When you run your feature again with bin/cucumber features/creating_states<br />

.feature, you see that the find_by_default method isn’t defined:<br />

And I follow "Make default" for the "New" state<br />

undefined method `find_by_default' for State...<br />

This dynamic method doesn’t exist because you haven’t yet defined the default column<br />

on your states table. If you had this column then Rails would have already<br />

defined the find_by_default method for you. To do this, you generate a migration<br />

that will add this column using the following command:<br />

rails g migration add_default_to_states default:boolean<br />

B Dynamic finder<br />

C Change default state<br />

Don’t run this migration just yet. With the default column being a boolean field, it’s<br />

going to need to know what its default value should be: either true or false. To set a

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

Saved successfully!

Ooh no, something went wrong!