Ruby on Rails/ActiveRecord/Attributes
Attributes
[edit | edit source]ActiveRecord attributes are automatically determined from the underlying database schema.
Basic Usage
[edit | edit source]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 products, 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 readable.
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 | edit source]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).