2.7. BehaviorActive Record lets you manipulate and find table data directly through Active Record classes and instances. If you want to work with data from a table, use the class. If you want to work with a table row, use an instance. ActiveRecord::Base class supplies many of the methods , and missing_method provides most of the rest. You can find the documentation for the latest stable Active Record version online at the following address: http://api.rubyonrails.com. 2.7.1. FindersYou can use other finders as well. find_by_sql lets you type SQL directly into a finder; find_all returns all records. In addition, Active Record adds a custom finder called find_by_<column_name> to each model class for each column in that model's table. Let's use some of the methods on Photo . We'll use a finder and the destroy method to delete an object from the database: Photo.find_by_filename("balboa_park.jpg").destroy The methods delete and destroy are slightly different. delete aborts on minor errors, but destroy does not abort unless there's a critical database error. You can also update objects. Let's update the Photo object for cat.jpg : >> cat=Photo.find_by_filename "cat.jpg" ... >> cat.filename="Cat.jpg" ... >> cat.update ... >> puts cat.reload.filename Cat.jpg ... In this case, we found the cat.jpg record. We next updated the filename attribute and called update to write the changes to the database. 2.7.2. ValidationSo far, you've used Active Record to do database operations on an object. You can also use Active Record for simple validation. For example, you can verify that the filename property exists with one line of code. Change the Photo class in app/models/photo.rb to look like this: class Photo < ActiveRecord::Base validates_presence_of :filename end Let's see how the validation works. Go back to the console (you'll need to restart it to reload your changes), and try to save a blank photo: >> photo=Photo.new => #<Photo:0x3501b70 @attributes={"filename"=>""}, @new_record=true> >> photo.save => false The save failed. Let's find out why: >> photo.errors.each {attribute, error puts attribute + ": " +error} filename: can't be blank => {"filename"=>["can't be blank"]} You can do several different kinds of validation, or you can create your own. You could validate an email message like this: validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i Or you could validate the length of a field like this: validates_length_of :name, :within => 6..100 Later, you'll see that the Rails view integration uses this information to present meaningful error messages; look for those details in Chapter 5. You've seen the basics of working with Active Record classes. You use a model object or its class to directly manipulate rows in the database table. Active Record goes beyond most traditional wrapping frameworks because it helps you manage relationships between tables. In the next few sections, let's look into how Active Record manages simple relationships. 2.7.3. TransactionsPhoto Share doesn't require transactions, but for many applications, transactional behavior is critical. If you have some code that must be executed as a single unit, you can use Active Record transactions. The most common example is a transfer between two accounts. A transfer is fundamentally a debit and a credit. The Ruby code for a transfer between from and to Active Record Account models might look like this: def transfer(from, to, amount) from.debit(amount) to.credit(amount) end You wouldn't want this method to fail after the debitif it did, the holder of the from account would be shorted by amount . So you use a transaction. This is the way it works: def transfer(from, to, amount) Account.transaction do from.debit(amount) to.credit(amount) end end transaction is a method on all Active Record classes. With this approach, you can maintain the integrity of your transactions. |