Ruby on Rails/ActiveRecord/Attributes

From Wikibooks, open books for an open world
< Ruby on Rails‎ | ActiveRecord
Jump to: navigation, search

Attributes[edit]

ActiveRecord attributes are automatically determined from the underlying database schema.

Basic Usage[edit]

All of the columns in a table are accessible through methods on the ActiveRecord model. For example:

Consider the following migration:

# 20090409120944_create_products.rb
class CreateProducts < ActiveRecord::Migration
  def self.up
    create_table :products do |t|
      t.string :name
      t.float :price
      t.integer :amount
    end
  end
#...
end

Because Rails has created a primary key for us and called it "id" we can already search for it inside the database. We can interact with the database via the build-in console:

 ruby script/console

gives us a console that let us communicate with Rails.

Before we can select data from our database it is time to insert some products

 >> Product.new(:name => "my book", :price => 14.99, :amount => 4).save

if everything went right, Rails will show you a =>true inside the console... Let's add some more products

 >> Product.new(:name => "my movie", :price => 4.89 :amount => 1).save
 >> Product.new(:name => "my cd", :price => 9.98, :amount => 12).save

Now we have 3 products in our database, going from 1 to 3...

So let's select the first entry

 >>Product.find(1)

and Rails tells you what it found for this id (remember: find only works when there is a Rails generated id as primary key)

 => #<Product: id=1, name="my book" ..... >

so we are able to tell Rails to look for our entry with a specific id. But what happens when we have thousands of entries in our database? We can't remember every id of a Product, so Rails offers a very nifty solution:

 >>Product.find_by_name("my book")
 => #<Product: id=1, name="my book" ..... >

and Rails gives as the output we wanted. This not only works for the name, but for all columns in the database. We could also use .find_by_price or .find_by_amount

Or you can search for multiple products with their id:

>>Product.find(1,3)

=> #<Product: id=1, name="my book" ..... ><Product: id=3, name="my cd" ..... >

You can also search for all products

 >>Product.all

or

 >>Products.find(:all)

for the first or the last product in your table

 >>Product.first/last

or

 >>Product.find(:first/:last)

If you want more controll over your data, you can use many build-in options or use custom SQL. Let's try to find our data in descending order (3,2,1)

 >>Product.all(:order => "id DESC")

or alternatively

 >>Product.find(:all, :order => "id DESC")

will give you all your prodcuts, starting with the last inserted id - in our case: 3


When we query our database we get lots of infos we are not really interested in such as the "created_at" and "updated_at" column. We only want to take a look at our id and the name so we may use

 >>Product.all(:select => "id, name")

or

 >>Product.find(:all, :select => "id, name")

This method will only display the name and the id of our products making it way more readabel.

When searching for data, keep in mind that you can combine all these methods to your liking. To see more possibilities check out the RoR guide or the API.

Overriding Attributes[edit]

You can override any of the accessor methods in your ActiveRecord model classes in order to add logic. For example:

  class Product
    def name
      self[:name] || 'Unknown'
    end
  end
 p = Product.new
 p.name
 => "Unknown"
 p.name = 'my disk'
 p.name
 => "my disk"

You can access any attribute via self[attribute_name] (to get) or self[attribute_name]= (to set).