Error: Association is already on schema

To save on unnecessary indices, I would like to use the primary key as a foreign key (in my case because I am using class table inheritance).

So I have something like this as a migration:

create table(:base_class) do
  ...
end

create table(:derived_class) do
  add :base_class_id, :integer, references(:base_class),
                                   null: false,
                                   primary_key: true
  ...
end

Then, on the schema side I would like to use something like this to facilitate reuse in all derived classes (idea from the Ecto migration guide):

defmodule MyApp.DerivedClassExtensionSchema do
  defmacro __using__(_) do
    quote do
      use Ecto.Schema
      @primary_key {:base_class_id, :id, autogenerate: false}
    end
  end
end

Finally, the derived class schema looks like this:

defmodule MyApp.DerivedClass do
  use MyApp.DerivedClassExtensionSchema

  schema "derived_class" do
    belongs_to :base, MyApp.BaseClass
  end

end

The problem is that when I try to do this, I get a (ArgumentError) field/association :base_class_id is already set on schema.

Am I adding the primary key twice or something? My thinking is that the migration is what actually modifies the database, the schema is only a mapping from the database to Elixir structs, and the schema must be told if you plan to use a different PK than the default. But I am getting this error and I am not sure how to proceed.

Thanks for reading.

The problem with this appeared to be:

  1. That the migrations required a primary_key: false argument with the create table function. This took care of things on the DB side.
  2. The belongs_to function needed an option primary_key: true. Unfortunately, this did not take care of things on the schema side of things, as using an empty struct modeled after the schema still included an id field that is autogenerated–and a new problem was born. I tried to pass an autogenerated: false option but this is not supported in the belongs_to function. So… Unless there is a way to stop autogenerating an id column on the schema side of things, maybe this is a bug?
1 Like