Inserting a record

Ecto for Beginners : part 7 of 22 published on Sep 06, 2015

Now that we have Post defined as an Ecto model. We can use it to insert records into the database.

We could open up an iex console with the iex -S mix command and insert records there, but that code would be temporary.

Instead we are going to make tests to demonstrate how to use Ecto. That way the code is always around and is there for you to review anytime.

Setup Test

We will create all our insert tests here:

# /test/models/posts/insert_test.exs
defmodule Readdit.Posts.InsertTest do
end

Repo.Insert!

We can insert a record into the database by passing an Ecto model struct the Repo.insert!/1 function.

The insert! function if successful will return the inserted Post.

test "insert! post" do
  # initialize a Post struct with a value for the title field
  post = %Readdit.Post{title: "Han Shot First"}

  # pass the post to the Repo.insert!/1 function
  # get the inserted post as a return value
  inserted_post = Readdit.Repo.insert!(post)

  assert inserted_post.title == "Han Shot First"
end

Repo.Insert

We can also insert a record using the Repo.insert/1 function.

The difference between insert! and insert is that insert will return a tuple with information on whether the record was inserted successfully or if there was an error.

test "insert post" do
  post = %Readdit.Post{title: "Han Shot First"}

  { :ok, inserted_post } = Readdit.Repo.insert(post)

  assert inserted_post.title == "Han Shot First"
end

Model |> Repo.insert!

A common way of inserting a record with Ecto is to initialize the model and then use the pipeline operator (|>) to then call the Repo.insert!/1 function.

The pipeline operator takes the result from the left side and passes that as the first argument to the function on the right side.

test "post |> insert!" do
  inserted_post = %Readdit.Post{title: "Han Shot First"} 
    |> Readdit.Repo.insert!

  assert inserted_post.title == "Han Shot First"
end

Test Review

Our test class should pass and look like:

# /test/models/posts/insert_test.exs
defmodule Readdit.Posts.InsertTest do
  use ExUnit.Case
  use Readdit.ConnCase
  
  test "insert! post" do
    post = %Readdit.Post{title: "Han Shot First"}

    inserted_post = Readdit.Repo.insert!(post)

    assert inserted_post.title == "Han Shot First"
  end
  
  test "insert post" do
    post = %Readdit.Post{title: "Han Shot First"}

    { :ok, inserted_post } = Readdit.Repo.insert(post)

    assert inserted_post.title == "Han Shot First"
  end

  test "post |> insert!" do
    inserted_post = %Readdit.Post{title: "Han Shot First"} 
      |> Readdit.Repo.insert!

    assert inserted_post.title == "Han Shot First"
  end

end
Next: Get all records