Working with Rails from the Console

Rails is so thoroughly web-facing that it can be difficult to imagine working with it from the command line, but it does indeed offer script/console. (In Heroku, just choose Console from the gear menu, and it will bring up a console in a separate window.) When you run script/console rather than script/server, Rails starts up a special environment using the Interactive Ruby Shell (irb) instead of firing up a web server. This shell has the full context of your application, so you can load data from your databases, play with models, and generally take a look around.

Note

You can, if you want, have script/console and script/server running at the same time in different windows.

The console shell lets you interact with your application from the command line with the full powers of Ruby at your disposal. Most Ruby books include a lot more detail about irb, some even running all of their examples there, but in Rails it’s good mostly for playing with models and testing methods.

To get started, try running script/console --sandbox in one of your applications, say the final students/courses application from Chapter 9. You’ll see something like:

SimonMacBook:students001c simonstl$ script/console --sandbox
Loading development environment in sandbox (Rails 2.1.0)
Any modifications you make will be rolled back on exit
>>

If you actually want to make changes to your database, you can leave off the --sandbox option (which can be abbreviated -s). For the first few visits, it feels safer to know that none of the changes made from the console will last beyond the console session. Everything gets rolled back once the session ends.

To start actually working with some data, load an object into a variable. Rails will not only load the object, it will show all the details of the underlying fields. (It always shows the return value.)

>> s=Student.find(2)
=> #<Student id: 2, given_name: "Milletta", middle_name: "Zorgos", family_name:
"Stim", date_of_birth: "1989-02-02", grade_point_average:
#<BigDecimal:1e8104c,'0.394E1',8(8)>, start_date: "2006-09-12", created_at: "2008-
07-03 18:34:59", updated_at: "2008-07-03 18:34:59">

The model included something that isn’t shown here, though: a simpler name method. You can call that from the console, too:

>> s.name
=> "Milletta Stim"

All of the methods on the model are available to you here. In fact, if you’re going to be working with one object for a long time, you can create a new irb console session that’s in the context of that object. This lets you call methods and explore without constantly prefacing method names with the variable you used:

>> irb s
>> name
=> "Milletta Stim"
>> cList=courses
=> [#<Course id: 1, name: "Reptiles: Friend or Foe?", created_at:
"2008-07-05 18:05:04", updated_at: "2008-07-05 18:05:04">,
#<Course id: 5, name: "Advanced Bolt Design", created_at: "2008-07-05
18:06:35", updated_at: "2008-07-05 18:06:35">]
>>

When you’re done working inside of this object, you can just type quit or exit, and you’ll be back at a >> prompt, but no longer in the object.

You can, of course, change the values in your objects as well:

>> s.middle_name='Zorgas'
=> "Zorgas"

If you want to see what values have changed—before you save them—you can use the y method (for YAML, a convenient data exchange format):

>> y s
--- !ruby/object:Student
attributes:
  start_date: "2006-09-12"
  updated_at: 2008-07-03 18:34:59
  id: "2"
  given_name: Milletta
  family_name: Stim
  date_of_birth: "1989-02-02"
  middle_name: Zorgas
  grade_point_average: "3.94"
  created_at: 2008-07-03 18:34:59
attributes_cache: {}

changed_attributes:
  middle_name: Zorgos
=> nil
>>

You can also call the save method:

>> s.save
=> true

The reported return value is true, so the save succeeded. (When the sandboxed session ends, this will be rolled back.)

The console provides two convenience objects you may want to use on their own. The first, helper, gives you instant access to all of the helper methods in your application. If you want to test out a method with a set of arguments, just call the method from helper, as in this call to number_to_human_size:

>> helper.number_to_human_size 1092582135
=> "1 GB"

The other convenience object, app, gives you access to your full application context, including the routing table. This lets you do things like test your routing with:

>> app.url_for :action=>"index", :controller=>"courses"
=> "http://www.example.com/courses"
>> app.url_for :action=>"new", :controller=>"courses"
=> "http://www.example.com/courses/new"

You can also test named routes, which are ubiquitous in RESTful development, but first you need to activate access to the methods which present them with:

>> include ActionController::UrlWriter

Then you can do things like:

>> new_course_path
=> "/courses/new"

You can also call your controllers using the app object, using the app.get, app.post, app.put, and app.delete methods from ActionController::Integration::Session. The results of these may not be exactly what you expect. For example:

>> app.get "/students/2"
=> 200

The 200 just means that the request was processed successfully and some kind of response produced. A 404 would be the classic “Not Found” error, meaning that Rails couldn’t find an action matching that path. You can take a closer look at what happened by asking the app object for the parameters:

>> app.controller.params
=> {"action"=>"show", "id"=>"2", "controller"=>"students"}

This breakdown makes it clear how the routing interpreted the request and called the controller. You can also get to the response itself, though the presentation isn’t quite beautiful:

>> app.response.body
=> "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="content-type" content="text/html;charset=UTF-8" />

<title>Students: show</title>
  <link
href="/stylesheets/scaffold.css?1215267158" media="screen" rel="stylesheet"
type="text/css" />
</head>
<body>
<p>
	<a
href="http://www.example.com/students">Students</a> |
	<a
href="http://www.example.com/courses">Courses</a>
</p>

<hr />
<p
style="color: green"></p>

<p>
  <b>Given name:</b>
  Milletta
</p>

<p>

<b>Middle name:</b>
  Zorgas
</p>

<p>
  <b>Family name:</b>

Stim
</p>

<p>
  <b>Date of birth:</b>
  1989-02-02
</p>

<p>
  <b>Grade
point average:</b>
  3.94
</p>

<p>
  <b>Start date:</b>
  2006-09-
12
</p>

<p>
  <b>Courses:</b>
  
	<a href="/courses/1">Reptiles: Friend
or Foe?</a>, <a href="/courses/5">Advanced Bolt Design</a>
  
</p>

<a
href="/students/2/edit">Edit</a> |
<a href="/students/2/courses">Courses</a>
|
<a href="/students/2/awards">Awards</a> |
<a
href="/students">Back</a>


</body>
</html>
"

You can also see all of the header information, doubtlessly more than you explicitly set:

>> app.headers
=> {"cache-control"=>["private, max-age=0, must-revalidate"], "status"=>["200 OK"],
"etag"=>[""34cbf61016b9bd898bb3df9eec96dc79""], "content-type"=>["text/html;
charset=utf-8"], "x-runtime"=>["0.16691"], "set-cookie"=>[], "content-
length"=>["1148"]}

If you’re working from the console and making changes to the code at the same time, there’s one more key command you’ll want to know: reload!. Rails’ console isn’t as instantly adapting, even in development mode, as its web interfaces. When you issue the reload! command, the console will reload your updated application code and use it. There’s just one thing to watch out for, though: if you’ve created objects already, they’ll still be using the old code. You’ll need to tear them down and replace them if you want to test them out with the new code.

The console is a great place to “get your hands dirty” and play with code directly. It lets you tinker with your application much more directly than is easily possible through the web interface. However, it definitely has some limitations. It’ll probably take a while to grow comfortable using it—the error messages are often cryptic. It’s obviously not a great place to experiment with interfaces. It’s very easy to enter a typo and not figure it out before something important has changed or broken.

Most importantly, though, the console is outside of your main application flow. Testing in the console is not usually testing the way the application really works. Not only that, it’s not a structured set of tests so much as poking around to see what happens. While the console is useful, it’s definitely not your only or best choice for making sure your application behaves correctly.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset