DEV Community

victorhaynes
victorhaynes

Posted on

ActiveRecord (a Ruby gem): Common Methods

ActiveRecord is popular Ruby gem (library) that acts as an Object-Relational-Mapper (ORM) for Ruby.

ActiveRecord allows us to combine the object-oriented nature of Ruby with the functionality of relational databases. Using ActiveRecord we can easily define Ruby Classes and map those Classes to columns in a database. We can then instantiate--i.e. create--new instances of those Ruby Classes and map those instances to records (rows) in a database column. We can then finally interact with our newly constructed database with methods from the ActiveRecord gem inside of a Ruby/.rb file.

Before continuing please note that ActiveRecord uses strict naming conventions. This is what allows its default configuration to handle a lot of work for us.

  • capitol, singular Class name for your model (Food)
  • lowercase, plural table names (foods)

Suppose we have this table of foods (from a Food Ruby class model that inherits from ActiveRecord::Base if you are keeping track at home) :

Table: foods

id name tastiness
1 hotdog 8
2 burger 7
3 ramen 9
4 rice 10
5 cheese 4

We could begin to access or manipulate this table using the Food class in a rake console session for example or in the model's .rb file. Here are some common methods & manipulations:

get first record

Food.first

=> <Object Instance corresponding to id:1 name: "hotdog" tastiness: 8>
Enter fullscreen mode Exit fullscreen mode
  • returns the first record/Object instance in a column

get record by id

Food.find(3)

=> <Object Instance corresponding to id:3 name: "ramen" tastiness: 9>
Enter fullscreen mode Exit fullscreen mode
  • returns the first record/Object instance with the id passed as an argument

get record by attribute (first match only)

Food.find_by(name: rice)

=> <Object Instance corresponding to id:4 name: "rice" tastiness: 10>
Enter fullscreen mode Exit fullscreen mode
  • returns the first record/Object instance with an attribute that matches the .find_by() argument

get all records by criteria (all matches)

Food.where(' tastiness < 8 ')

=> [<Object Instance corresponding to id:2 name: "burger" tastiness: 7>,
<Object Instance corresponding to id:5 name: "cheese" tastiness: 4>]
Enter fullscreen mode Exit fullscreen mode
  • returns all records/Object instances with an attribute that matches what was passed as an argument
  • .where returns an ActiveRecord::Collection which is an array-like data structure that can be indexed or iterated through using array methods. Even if there is only 1 match .where will always return the results in a collection.

get all values in a column

Food.pluck(:name)

=> ["hotdog", "burger" , "ramen", "rice", "cheese"]
Enter fullscreen mode Exit fullscreen mode

Food.pluck(:tastiness)

=> [8, 7 , 9, 10, 4]
Enter fullscreen mode Exit fullscreen mode
  • returns each value in a column as an element in an array

create a new record/instance in a table (with persistence)

Food.create(name: "eggs", tastiness: 5)

id name tastiness
1 hotdog 8
2 burger 7
3 ramen 9
4 rice 10
5 cheese 4
6 eggs 5
  • under the hood this is working similar to using .new & .save together. .new will only create a new instance of a class in Ruby memory. It will not persist until it is written to the database using .save. .create does both of these for you.

count number of records in a column

Food.count(:name)

=> 6
Enter fullscreen mode Exit fullscreen mode
  • counts the number of records in a column

remove a record/instance in a table (with persistence)

Food.find(2).destroy

id name tastiness
1 hotdog 8
3 ramen 9
4 rice 10
5 cheese 4
6 eggs 5
  • .destroy should be used to destroy a single record/instance
  • .destroy_all should be used to destroy multiple records such as every instance of a class (i.e. Food.destroy_all) or to destroy every member of an ActiveRecord::Collection (i.e. after a .where to do a targeted removal)

update a record/instance in a table (with persistence)

Food.find(6).update(name: "bread", tastiness: 9)

id name tastiness
1 hotdog 8
3 ramen 9
4 rice 10
5 cheese 4
6 bread 9
  • you can update a single attribute such as only the name or only the tastiness or do both

You are now familiar with basic ActiveRecord ORM methods. If you want to try experimenting with this data at home continue below:


Set this up at home:

Provided you have an Ruby & ActiveRecord environment already configured and you are in that directory, you can try this yourself after creating (and migrating) this migration:

Brief configuration guidance:
Gemfile:

source "https://rubygems.org"

gem "activerecord", "~> 5.2"
gem "sinatra-activerecord"
gem "sqlite3"
gem "pry"
gem "require_all"
gem "rake"
Enter fullscreen mode Exit fullscreen mode

Rakefile:

require_relative 'config/environment'
require 'sinatra/activerecord/rake'

desc 'starts a Pry console'
task :console do
  # Comment out the line below if you don't want to see the SQL logs in your terminal
  ActiveRecord::Base.logger = Logger.new(STDOUT)
  # Start a Pry session
  Pry.start
end
Enter fullscreen mode Exit fullscreen mode

config/database.yml:

development:
  adapter: sqlite3
  database: db/development.sqlite3
  pool: 5
  timeout: 5000

Enter fullscreen mode Exit fullscreen mode

config/environment.rb:

require 'bundler'
Bundler.require

require_all 'app'

Enter fullscreen mode Exit fullscreen mode

Now, on to actually creating this database:

# In a terminal window run:
$ bundle install
$ bundle exec rake db:create_migration NAME=create_foods
Enter fullscreen mode Exit fullscreen mode
# inside of the db/migrate folder
# update your migration to have these attributes
# (the 5.2 should match whatever version of the activerecord gem
# you have installed in your gemfile)

class CreateFoods < ActiveRecord::Migration[5.2]
  def change
    create_table :foods do |t|
      t.string :name
      t.integer :tastiness
    end
  end
end

Enter fullscreen mode Exit fullscreen mode

migrate your newly created migration:

# In a terminal window run:

$ bundle exec rake db:migrate
Enter fullscreen mode Exit fullscreen mode

create this model:

# create a /app folder inside the root of your directory and put a /models folder inside of it.
# create a .rb file with your model name inside of /models 
# singular and lowercase i.e. /app/models/food.rb

class Food < ActiveRecord::Base
end
Enter fullscreen mode Exit fullscreen mode

populate/seed your database with data (create instances of the Food class that will exist inside of your foods table

# create a "seeds.rb" file inside of the /db directory

Food.create(name: "hotdog", tastiness: 8)
Food.create(name: "burger", tastiness: 7)
Food.create(name: "ramen", tastiness: 9)
Food.create(name: "rice", tastiness: 10)
Food.create(name: "cheese", tastiness: 4)
Enter fullscreen mode Exit fullscreen mode
# In a terminal window run:

$ bundle exec rake db:seed
Enter fullscreen mode Exit fullscreen mode

You have now:
1) Defined your table structure
2) Created your table
3) Defined what class belongs your the table
4) Filled your table with instances of your class

You can new view your database using an IDE + an extension (such as Visual Studio Code /w the SQLite extension or using a standalone database viewer app).

Feel free to try access and manipulate your table inside of a rake console session in your terminal or from inside your model's class definition now.

Happy rubying!

Top comments (0)