|
|
BROWSE
All Titles WordPress Web Services SOA BPEL Web Graphics & Video Web Development RAW Portugues, Espanol, Italiano, French PHP/MySQL Oracle Open Source Networking & Telephony Moodle Microsoft & .NET Linux Servers jQuery Joomla! JBoss Java e-Learning e-Commerce Dynamics Drupal CRM Cookbook Content Management Beginner Guides Architecture and Analysis AJAX Future Titles Recently Published Titles TOP TITLES ![]()
|
Working with Rails – Setting up and connecting to a database
In this article, authors Elliot Smith and Rob Nichols explain the setup of a new Rails application and how to integrate it with other data sources. Specifically, this article focuses on turning the abstract data structure for Intranet into a Rails application. This requires a variety of concepts and tools, namely:
In this article, we'll focus on the first 3 concepts. The World According to RailsTo understand how Rails applications work, it helps to get under its skin: find out what motivated its development, and the philosophy behind it. The first thing to grasp is that Rails is often referred to as opinionated software (see http://www.oreillynet.com/pub/a/network/2005/08/30/ruby-rails-davidheinemeier-hansson.html). It encapsulates an approach to web application development centered on good practice, emphasizing automation of common tasks and minimization of effort. Rails helps developers make good choices, and even removes the need to make choices where they are just distractions. How is this possible? It boils down to a couple of things:
We'll see each of these features in more detail in the next two sections. Model-View-Controller ArchitectureThe original aim of the MVC pattern was to provide architecture to bridge the gap between human and computer models of data. Over time, MVC has evolved into an architecture which decouples components of an application, so that one component (e.g. the control logic) can be changed with minimal impact on the other components (e.g. the interface). Explaining MVC makes more sense in the context of "traditional" web applications. When using languages such as PHP or ASP, it is tempting to mix application logic with database-access code and HTML generation. (Ruby, itself, can also be used in this way to write CGI scripts.) To highlight how a traditional web application works, here's a pseudo-code example: # define a file to save email addresses into The highlighted comments indicate how the code can be mapped to elements of the MVC architecture:
In a traditional web application, the three broad classes of behavior described above are frequently mixed together. In a Rails application, these behaviors are separated out, so that a single layer of the application (the model, view, or controller) can be altered with minimal impact on the other layers. This gives a Rails application the right mix of modularity, fl exibility, and power. Next, we'll see another piece of what makes Rails so powerful: the idea of using conventions to create associations between models, views, and controllers. Once you can see how this works, the Rails implementation of MVC makes more sense: we'll return to that topic in the section Rails and MVC.
Convention over ConfigurationIn the previous section, we met the MVC framework, used to define the general design of every Rails application. The MVC framework naturally breaks an application into three groups of components (models, views, and controllers). In the "olden" days, a web application framework would typically define relationships between these components using a configuration file (e.g. an XML file in the Struts framework). Writing this configuration file was often a laborious and error-prone task, and could take the same amount of time as writing the application code itself. The Rails developers recognized that, most of the time, the relationships between the parts of an MVC application are obvious, repetitive, and shouldn't require configuration. There tends to be a common set of actions associated with each controller ("show a list of model instances"; "show a single model instance"; "create, update, or delete a model instance"); and developers will tend to give them similar names (list, show, delete, update, create). This realization prompted the Rails developers to create a set of conventions around how common application components are implemented: standards for class names and locations, controllers and actions, fi le names, and directory structure. Rail uses these conventions to minimize the need for configuration, automatically generating much of it when the application is bootstrapped. As well as simplifying configuration, the conventions also remove the need for a developer to make certain decisions. In classical web applications, a developer would often have to decide where to put files and directories, and then have to define relationships between application elements (e.g. which views are used by which controller). By contrast, every Rails application has a familiar directory structure, automatically generated by tools; each file added to the project usually adheres to a naming standard; classes follow a similar naming convention; and there are conventions for naming and locating supporting files, like Javascripts and images. By making choices for the developer, Rails can save time (and sometimes arguments), leading to its much touted productivity gains. If you need to, you can step outside the Rails conventions. Mostly, though, there is no need to, and you can greatly reduce development time by embracing the conventions instead. Rails and MVCAt its core, the architecture of Rails is standard MVC; however, unlike older forms of MVC for the web, Rails minimizes the effort needed to maintain the MVC pattern. This is because the conventions inherent in Rails, as described in the previous section, reduce the need for configuration. The diagram, below, gives a graphical representation of how Rails implements MVC, and also summarizes how conventions are used to define the workflow of an application. Our fledgling Intranet application is used as an example; specifically, the page which displays a list of people: Fleshing out the steps in the diagram, here's what happens when a client requests a list of people:
As you can see, the Rails conventions enable some powerful connections between aspects of the model, view, and controller components, with no need for configuration. The Rails "power tools" are the keys to leveraging its conventions, namely:
We'll see how to use these tools in the following sections, as we start building the Intranet application. Books from Packt Setting Up a New Rails ApplicationEvery Rails application looks basically the same. Each has the same directories, and even files with the same names. The reason for this is that Rails provides a command (rails) for creating a stock set of directories and stub files as a starting point for any new application, to be fleshed out as development progresses. These files and directories are arranged in such a way that the different parts of Rails (in fact, it is a framework of frameworks) can work together effectively. When starting a new application, running the rails command is the first step. If you you already have an empty Intranet directory inside your Eclipse workspace, "connected" to the code repository, then rather than create a new directory for your application, you can use this existing one for your application as shown below: $ cd workspace (Note that you may need to replace workspace with the directory you are using for your Eclipse workspace.) More generally, use this command from a prompt to start a new Rails application in situations where you haven't created a project directory yet: $ rails /path/to/application When you run the rails command, you should see something like this $ rails Intranet (This has been truncated for brevity: the rails command generates a lot of stuff.) The absolute path to the top-level directory containing the application is referred to inside Rails as the RAILS_ROOT directory. In our case (as we're developing with Rory), this directory is: /home/rory/workspace/Intranet Rather than going into too much detail, below is a summary of what is contained in a fresh RAILS_ROOT directory. Directories which are particularly important are marked with an asterisk, as we'll be spending most of our time inside them:
If you switch to Eclipse to browse your new Rails application, you might wonder where the files have gone. This is because Eclipse doesn't monitor changes to the filesystem. When we added our application files outside Eclipse (by running the rails command), Eclipse didn't know anything about it. The solution is to refresh Eclipse's view of the filesystem. Right-click on the name of the project and select the Refresh option from the context menu. You should now be able to see your files. Now we have a skeletal application, we are finally ready for some magic. Using Mongrel to Serve Your ApplicationI expect you're dying to see your fi rst Rails application up and running? It turns out this is no work at all. Connect into your application's directory using the command line, and run the following command: $ ruby script/server Or, on Windows: $ ruby scriptserver We'll be using the Linux-style syntax throughout the book when running the scripts, with forward slashes as path delimiters. This command runs one of the Rails built-in scripts, located in the script directory, which starts a Mongrel server whose single purpose is running your Rails application. If the server starts correctly, you should see: => Booting Mongrel (use 'script/server webrick' to force WEBrick) Note that the application is served on port 3000 by default and is accessible at the URL http://localhost:3000/. If you open this URL in a browser, you should see something like this: Click on the About your application's environment link to see some information about the versions of Ruby and Rails you are running with. On Linux, you can dispense with the ruby command and just use this command to run the server: $ script/server The only requirement for this to work is that the script should be able to find your Ruby binary. This is defined in the shebang line (the first line of the file). Usually, the default line works correctly: #!/usr/bin/env ruby However, if your Ruby installation isn't in your PATH environment variable, you may have to modify the ruby part of this line to point at its location. For example, if your Ruby installation is in /opt/ruby1.8.4 you would use the shebang: #!/usr/bin/env /opt/ruby1.8.4/bin/ruby Our application isn't too exciting so far, we can't interact with it very much, and it has little data to serve. In the next sections, we're going to build it up, taking a data-centric approach. As of Rails 1.2, if Mongrel is installed on your machine, it is used as the default web server for your application. However, if you don't have Mongrel installed, Mongrel isn't on your path, or you are using an lder version of Rails, WEBrick is used instead. The only difference is that WEBrick is significantly slower, and not suitable for running Rails applications in a production environment. Other than that, you can happily develop an application using either. Connecting Rails to a DatabaseThroughout decades of client-server computing, the architecture of database driven applications has been designed by database administrators working in the "enterprise". This architecture places the responsibility for managing data squarely in the database itself. Applications are considered "dumb", not to be trusted with vital tasks like data validation and formatting, or managing relationships between different tables. Using this traditional architecture, we might manage our Intranet application's data structures like this:
By contrast, in the Rails view of the world, the application is king, and the database is its servant. This is due to Rails being the product of web developers: in the web development environment, databases are typically unsophisticated buckets for holding "stuff" (because they are often designed by people who aren't full-time database administrators). However, beyond this, performing database operations through model classes simplifies database access considerably: making a change to an application can be done in the high-level application code, rather than by modifying low-level SQL code in the database layer. Therefore, operations, which would be delegated to the database in the traditional client-server architecture (such as the ones in the bullet points above) are instead handled by ActiveRecord in a Rails application. ActiveRecord is a so-called object-relational mapping (ORM) layer (also known as a relational persistence layer), similar in scope to Hibernate (Java) or ADODB (PHP). Instead of dealing with the database through SQL statements, an ORM layer presents records in a database table as a series of objects; it also provides class-level methods for creating database connections, querying tables, and so on. The fi elds in a record are not read or written directly, but accessed through instance methods on an object. This reduces the complexity and tedium of working with a relational database, as the onus for creating database connections, correctly formatting SQL statements, escaping quote marks in strings, etc. is moved into the ORM layer, away from the developer. Bruce Tate and Curt Hibbs call ActiveRecord an Object Relational Wrapping layer, rather than a Mapping layer: their view is that as there is no explicit configuration of the relationship between the model classes and the database tables, it doesn't count as a "mapping". They have a point, but the exact semantics aren't too important. Here, I'm treating "mapping" in the sense that objects can be mapped onto records in the database tables. An ORM layer is one way to implement the model part of the MVC architecture, and this is the role ActiveRecord fulfils in a Rails application: it acts as the intermediary between the controller and the database, retrieving, validating, updating, and deleting records on behalf of the controller. Before we can see how this works, we need a database to use as the back-end for our application. Setting this up is covered in the following sections. Creating a Database and System AccountWe're going to use MySQL as the database back-end for the Intranet application. If you followed the installation instructions, you should have MySQL available on your machine. These instructions cover how to setup a database and user in MySQL. However, if you have an alternative database back-end (Oracle, SQL Server, PostgreSQL, etc.), create a database and a user with whichever tools that are appropriate for your database instead. The first step is to initialize the MySQL database. You could use one of the MySQL GUI clients to do this, but we'll use the command line as this works the same regardless of your platform. Use this command to login to the database server on your local machine: $ mysql -u root -p Note that -u root specifies we are logging in as the root user: you need to use an account with sufficient privileges to create a new database. -p indicates that we intend to use a password to login. If your login is successful, you should see: Welcome to the MySQL monitor. Commands end with ; or g. Once you've logged in successfully, create a database called intranet_development with: mysql> CREATE DATABASE intranet_development; This is the database we'll be using during the development of our application. The next step is to create a user account for our Rails application. T his is a good practice: instead of using a real person's account (or even worse, the root account) to connect our Rails application to MySQL, we will use a dedicated system account. This gives us a handful of security advantages:
Again, you can use either a GUI tool or the command line to create the system account. Here's how to do it on the command line (once you are logged in to MySQL): mysql> GRANT ALL ON intranet_development.* TO intranet@localhost This simultaneously creates the intranet user account and gives that user all permissions (known as privileges in MySQL) on the intranet database. The IDENTIFIED BY clause specifies the account password ('police73'). @localhost specifies the host name from which this user can access the database. If the database server is on a separate physical box from the application server, the application server's IP address or domain name should be used here. FLUSH PRIVILEGES applies the permissions to the server. A note on permissions In the example above, the system account is given all permissions on the database. You may not want to give your application this level of access to the database, once it is in production. MySQL makes it trivial to restrict permissions on individual tables or columns within tables and/or by SQL operation (e.g. the production system account could just be given SELECT permissions if the application just reads from the database tables).
Setting Up a Database ConnectionThe database connection settings for a Rails application are stored in a single file called database.yml, inside the config directory (which is in turn inside the RAILS_ROOT). The freshly-minted database.yml file (produced by the rails command) can seem a bit confusing, mainly because it contains a lot of examples and hints. However, after removing comments, it boils down to this: development: This is a YAML (rhymes with "camel") file, which configures the database settings for each of the three Rails' environments: development, test, and production—which is explained in the next section). YAML, ( "YAML ain't a Markup Language"), is officially described as a "data serialization language" (see, http://yaml.org/). Its purpose is comparable to that of XML: both YAML and XML are used to define configuration settings, log file formats, or other kinds of structured data. However, YAML has the following benefits over XML:
The YAML syntax used in the database.yml file defines a YAML mapping from keys to values. (If you've ever worked with a configuration file, the key-value concept should be familiar.) When the file is read by Rails, it is converted into a Ruby hash (c.f. a dictionary or associative array in other languages). The words which are flush with the left of the file ('development', 'test', 'production') are the keys of this top-level hash; in Ruby syntax, the hash looks like this: {
Underneath each of these top-level keys is a series of name-value pairs; each series is also converted into a hash. The parent key has this hash as a value. In Ruby syntax, the resulting "hash of hashes" looks like this: {
(The 'test' and 'production' sections are truncated for brevity.) Each sub-hash specifies a database configuration for one of the Rails environments,as described in the next section. Configuring the Rails EnvironmentsRails can run an application in different modes; each mode is known as an environment. Each environment is kept isolated from the others, uses a different database, and handles logging and error checking differently. This makes it possible to develop your code without breaking the live application, run tests without wiping records from the live database, and run your application more efficiently in production (amongst other things). The three environments have different purposes and characteristics:
You can configure database settings by editing the section of the database.yml file named after the environment. For now, we'll just edit the settings for the development environment: development: You must use spaces, not tabs, in a YAML file: attempting to use tabs in a YAML file will break it completely. For reference, so that you can recognize it in case it happens to you, here's a YAML error caused by an errant tab: /usr/lib/ruby/1.8/yaml.rb:133:in 'load': syntax error on There is no need to configure the test and production databases at this point: we can leave the default settings as they are until we need these environments. Each line of the configuration is described in more detail in the table below:
Although we are using MySQL as our database server, ActiveRecord supports a range of other back-ends. You can specify which by changing the adapter configuration option to one of these values:
Each adapter has its own set of configuration options: see the Rails documentation for adapter-specific details. Some adapters have specific requirements, such as the installation of additional Ruby or native libraries. This may restrict your choice of server operating system for running your Rails application. For example, the sqlserver adapter requires the use of ODBC, which may in turn require you to install a variety of ODBC software on your application server (see http://wiki.rubyonrails.org/rails/pages/HowtoConnectToMicrosoftSQLServerFromRailsOnLinux). Make sure you are aware of all the pre-requisite software you need for some of the Rails database adapters. Testing the Database ConnectionIt is useful to check that the database connection is working before going any further. There's an easy way to do this. Start up a Rails console session using another of the built-in scripts Rails adds to your application called the console. Do this using the command line, by connecting into RAILS_ROOT and running: ruby script/console You should see: Loading development envir >> If you do, Rails has loaded your application's components correctly. The command prompt can now be used to enter commands, which directly manipulate your Rails application, without having to use a browser: very useful for general testing and tinkering. (We'll come back to the console throughout this article.) For now, enter this command to test your database connection: >> ActiveRecord::Base.connection If the database connection is working correctly, you should see: => #<ActiveRecord::ConnectionAdapters::MysqlAdapter:0xb74dbe34 ...> This has been truncated, as you get a lot of detail back from the console. But providing an ActiveRecord::ConnectionAdapters::MySQLAdapter instance has been successfully created, you can be happy that the database connection is working. If the database connection fails, you might see this instead: Mysql::Error: Can't connect to local MySQL server through socket '/var/ ...which means the socket location is wrong. Or: Mysql::Error: Access denied for user 'intranet'@'localhost' (usingpassword: ...which means the system account does not have access to the server and/or the database. The next section covers what to do if one of these errors occurs. Troubleshooting a MySQL ConnectionIf you discover that your MySQL connection isn't working (see the previous section),check the following:
Hopefully, you should be able to fix pretty much any MySQL connection error by following these steps. SummaryIn this article, we covered the various aspects of working with Rails. We looked at the Model-View-Controller Architechture, setting up a new Rails application, using Mongrel, and we also looked at how to connect Rails to a database and the related troubleshooting.
Elliot Smith has worked in IT since 1996: at OpenAdvantage (an open-source solutions center) as a business analyst, as a learning technologist and web developer at the University of Birmingham, England, and as a technical writer for Armada Computer Publications. He runs his own training and consulting company, mooch labs, when he gets a chance. He has an M.Sc. in Artificial Intelligence and a Ph.D. in Computer Science from the University of Birmingham. Rob Nichols first started using computers during his apprenticeship at Rolls-Royce in the early 1980s. At 23 he decided to change direction and started a degree in Geology and Geography at Cardiff University. By 1995 he had gained a Ph.D. from Bristol University, studying the behavior of quicksand. During his time in Bristol and in a subsequent lectureship at Leeds University, he started using the fledgling Internet to communicate with co-workers, gather information, and present Geological information in the form of his first web pages. Following his return to Britain from a lectureship in U.S.P. Fiji, Rob found himself without another lectureship position to go on to. So, changing direction again, he started working for a U.K. computer manufacturer, where he rose to the position of Engineering Manager, managing a team of seventy maintenance and networking engineers, and support staff. Following the collapse of the U.K. computer market in 2002 he moved on to the role of IT manager for a small business providing products and services to the water industry. In this role, Rob has had great success developing intranet-based business applications that streamline business processes, save time, and increase efficiency. In so doing he has transformed the IT department from a business cost to a profit generator by reducing costs and thereby increasing margins. When not working with computers, Rob and his wife reside happily in a small Midlands town in England, where he writes scripts for the local movie-makers club, and photographs the local wildlife. Books from Packt |
BOOK ![]() Ruby on Rails Enterprise Application Development: Plan, Program, Extend See More BOOK ![]() Xen Virtualization See More BOOK ![]() Professional Plone Development See More |
| ||||||||