Ecto changeset, enforcing inserts

Hi there,

I have two models, one representing an Transaction, the other describes the item that is to be traded. The item contains lots of detail data that can be changed. I want to track all these changes so the idea is to create a new Item for each change. So transaction has a list of items and foreign key to the current item.

  schema "transactions" do
    field :price
    field :status, :string

    has_many :items, Item
    belongs_to :item, Item
    timestamps()
  end

  schema "items" do
    belongs_to :transaction, Transaction
    embeds_one :data, DataStruct # jsonp containing all the details
    timestamps()
  end

Now when I receive an transaction with the associated item from the frontend I would like to overwrite the behavior of updating the existing item and instread save it as a new one. I managed to do that in a super hacky way, like saving the item in the first step by removing the id, and then updating the transaction and setting the item id. But I hope there is a smarter way. I think about changing either the the changeset of the transaction or the changeset of the Item to ensure inserts.

I really hope there is a way. Any hints, comments are highly appreciated. :slight_smile:

Marcus

1 Like

You should be able to do so by using Ecto.put_meta(struct, state: :built) to reset the state of the struct to build, this way you can insert it once again. However, you will have to remove any field you would like to be recomputed, such as IDs and timestamps.

1 Like