4.3. Adding Records

Actually, I would like to show you first how to view records, but there we have another chicken and egg problem. So first, here is how you can create a new record with ActiveRecord.

create

The most frequently used method for creating a new record is create. Let's try creating a country in the console with the command Country.create(name: 'Germany', population: 81831000)
$ rails console
Loading development environment (Rails 4.0.0)
>> Country.create(name: 'Germany', population: 81831000)
   (0.1ms)  begin transaction
  SQL (5.8ms)  INSERT INTO "countries" ("created_at", "name", "population", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Mon, 15 Jul 2013 17:58:19 UTC +00:00], ["name", "Germany"], ["population", 81831000], ["updated_at", Mon, 15 Jul 2013 17:58:19 UTC +00:00]]
   (1.0ms)  commit transaction
=> #<Country id: 1, name: "Germany", population: 81831000, created_at: "2013-07-15 17:58:19", updated_at: "2013-07-15 17:58:19">
>> exit
$
ActiveRecord saves the new record and outputs the executed SQL command in the development environment. But to make absolutely sure it works, let's have a quick look with the command line client sqlite3:
$ sqlite3 db/development.sqlite3 
SQLite version 3.7.12 2012-04-03 19:43:07
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> SELECT * FROM countries;
1|Germany|81831000|2013-07-15 17:58:19.600948|2013-07-15 17:58:19.600948
sqlite> .exit
$

Syntax

The method create can handle a number of different syntax constructs. If you want to create a single record, you can do this with or without {}-brackets within the the ()-brackets:
  • Country.create(name: 'Germany', population: 81831000)
  • Country.create({name: 'Germany', population: 81831000})
Similarly, you can describe the attributes differently:
  • Country.create(:name => 'Germany', :population => 81831000)
  • Country.create('name' => 'Germany', 'population' => 81831000)
  • Country.create( name: 'Germany', population: 81831000 )
You can also pass an array of hashes to create and use this approach to create several records at once:
Country.create([{name: 'Germany'}, {name: 'France'}])

new

In addition to create there is also new. But you have to use save to save an object created with new (which has both advantages and disadvantages):
$ rails console
Loading development environment (Rails 4.0.0)
>> france = Country.new
=> #<Country id: nil, name: nil, population: nil, created_at: nil, updated_at: nil>
>> france.name = 'France'
=> "France"
>> france.population = 65447374
=> 65447374
>> france.save
   (0.2ms)  begin transaction
  SQL (2.3ms)  INSERT INTO "countries" ("created_at", "name", "population", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Mon, 15 Jul 2013 18:07:03 UTC +00:00], ["name", "France"], ["population", 65447374], ["updated_at", Mon, 15 Jul 2013 18:07:03 UTC +00:00]]
   (3.0ms)  commit transaction
=> true
>> france
=> #<Country id: 2, name: "France", population: 65447374, created_at: "2013-07-15 18:07:03", updated_at: "2013-07-15 18:07:03">
>> 
You can also pass parameters for the new record directly to the method new, just as with create:
>> belgium = Country.new(name: 'Belgium', population: 10839905)
=> #<Country id: nil, name: "Belgium", population: 10839905, created_at: nil, updated_at: nil>
>> belgium.save
   (0.2ms)  begin transaction
  SQL (1.3ms)  INSERT INTO "countries" ("created_at", "name", "population", "updated_at") VALUES (?, ?, ?, ?)  [["created_at", Mon, 15 Jul 2013 18:08:07 UTC +00:00], ["name", "Belgium"], ["population", 10839905], ["updated_at", Mon, 15 Jul 2013 18:08:07 UTC +00:00]]
   (2.1ms)  commit transaction
=> true
>> exit
$

new_record?

With the method new_record? you can find out if a record has already been saved or not. If a new object has been created with new and not yet been saved, then the result of new_record? is true. After a save it is false.
Example:
$ rails console
Loading development environment (Rails 4.0.0)
>> netherlands = Country.new(name: 'Netherlands')
=> #<Country id: nil, name: "Netherlands", population: nil, created_at: nil, updated_at: nil>
>> netherlands.new_record?
=> true
>> netherlands.save
   (0.2ms)  begin transaction
  SQL (2.3ms)  INSERT INTO "countries" ("created_at", "name", "updated_at") VALUES (?, ?, ?)  [["created_at", Mon, 15 Jul 2013 18:08:52 UTC +00:00], ["name", "Netherlands"], ["updated_at", Mon, 15 Jul 2013 18:08:52 UTC +00:00]]
   (3.1ms)  commit transaction
=> true
>> netherlands.new_record?
=> false
>> exit
$

Buy the new Rails 5.1 version of this book.

For already existing records, you can also check for changes with the method changed? (see the section called “changed?”).