     :slot_internal_id => integer,
     optional(:link_component_id) => PK.t
   }
-  @type update_params :: %{link_component_id: PK.t}
+  @type update_params :: %{
+    optional(:link_component_id) => PK.t | nil
+  }
 
-  @creation_fields ~w/
-    motherboard_id
-    link_component_type
-    link_component_id
-    slot_internal_id/a
-  @update_fields ~w/link_component_id/a
+  @creation_fields ~w/motherboard_id link_component_type slot_internal_id/a
+  @accepted_fields ~w/link_component_id/a
+  @required_fields ~w/motherboard_id link_component_type slot_internal_id/a
 
   @primary_key false
   schema "motherboard_slots" do

    motherboard: Motherboard.t,
    motherboard_id: PK.t,
    component: Component.t,
    link_component_id: PK.t,
    link_component_type: String.t,
    inserted_at: NaiveDateTime.t,
    updated_at: NaiveDateTime.t

  def create_changeset(params) do
    %__MODULE__{}
    |> cast(params, @creation_fields)
    |> put_primary_key()
  end

  @spec update_changeset(t | Ecto.Changeset.t, update_params) :: Ecto.Changeset.t
  def update_changeset(struct, params) do
    changeset(struct, params)
  end

  def changeset(struct, params) do
    struct
    |> cast(params, @accepted_fields)
    |> validate_required(@required_fields)
    |> unique_constraint(:link_component_id)
  end

  @spec put_primary_key(Ecto.Changeset.t) :: Ecto.Changeset.t
