Create Foreign Key Relationship Between Ecto Tables: Difference between revisions

From ElixirBlocks
Jump to: navigation, search
(Created page with "{{In_progress}} My goal is to create two html generated tables in Phoenix. * Testbed(s) * Group(s) I want to create a relationship between these two tables so that: * A Group can have many Testbeds * Each Testbed can belong to 1 Group * I intend to write front end code that presents this relationship to the user. Steps In Phoenix I generated the two tables and related UI code using these commands: <source> mix phx.gen.html Testbeds Testbed testbeds name:string mi...")
 
No edit summary
Line 135: Line 135:


I now need to know how to write code that assigns a Testbed to a Group.
I now need to know how to write code that assigns a Testbed to a Group.
==Submit Testbed with Group Association==
<source>
group = App.Groups.get_group!(1)
thing = Ecto.build_assoc(group, :testbeds, name: "DUMB")
alias App.{Repo}
Repo.insert(thing)
</source>

Revision as of 14:25, 6 October 2023

This page is in progress


My goal is to create two html generated tables in Phoenix.

  • Testbed(s)
  • Group(s)

I want to create a relationship between these two tables so that:

  • A Group can have many Testbeds
  • Each Testbed can belong to 1 Group
  • I intend to write front end code that presents this relationship to the user.

Steps

In Phoenix I generated the two tables and related UI code using these commands:

mix phx.gen.html Testbeds Testbed testbeds name:string

mix phx.gen.html Groups Group groups name:string

The command line prompted me to add the resources / route for both of them. I did what it said.

I ran:

 mix ecto.migrate

Testbed Migration For testbeds, I create a migration file and add this field: group_id:references:groups.

def change do
    alter table(:testbeds) do    # customize to your code
      add :group_id, :references(:groups)
    end
  end

Change Group Schema I update Group schema. Changes in Comments

defmodule App.Groups.Group do
	use Ecto.Schema
	import Ecto.Changeset
	alias App.Testbeds.Testbed   # Alias!

	schema "posts" do
		field :body, :string
		field :title, :string
		has_many :testbeds, Testbed    # Has many

		timestamps()
	end

	@doc false
	def changeset(post, attrs) do
		post
		|> cast(attrs, [:title, :body])
		|> validate_required([:title, :body])
	end
end

Change Testbed Schema


defmodule App.Testbeds.Testbed do
  use Ecto.Schema
  import Ecto.Changeset
  alias App.Groups.Group      # Alias
  schema "testbeds" do
    field :name, :string
    belongs_to :group, Group    # Belongs to
    timestamps()
  end

  @doc false
  def changeset(testbed, attrs) do
    testbed
    |> cast(attrs, [:name])
    |> validate_required([:name])
  end
end

I read that I needed to incorporate “preload” so that I can submit data. So I did this:

  def list_testbeds do
    Repo.all(Testbed)
    |> Repo.preload([:group])
  end

and this

  def list_groups do
    Repo.all(Group)
     |> Repo.preload([:testbeds])
  end

When I query Groups they now look like this:


 %App.Groups.Group{
    __meta__: #Ecto.Schema.Metadata<:loaded, "groups">,
    id: 3,
    name: "FUNK",
    testbeds: [],
    inserted_at: ~N[2023-09-27 18:13:15],
    updated_at: ~N[2023-09-27 18:13:15]
  }

When I query Testbeds they now look like this:

%App.Testbeds.Testbed{
    __meta__: #Ecto.Schema.Metadata<:loaded, "testbeds">,
    id: 1,
    name: "Bloop",
    group_id: nil,
    group: nil,
    inserted_at: ~N[2023-09-27 14:04:15],
    updated_at: ~N[2023-09-27 18:22:23]
  }

I now need to know how to write code that assigns a Testbed to a Group.


Submit Testbed with Group Association

group = App.Groups.get_group!(1)
thing = Ecto.build_assoc(group, :testbeds, name: "DUMB")
alias App.{Repo}
Repo.insert(thing)