Proposal for farmOS 3.x core datamodel improvements: Immutable Quantities & Soft Entity Deletion

I wanted to open this thread to test the waters for a couple of (I feel) key improvements to the core farmOS datamodel that should be considered for a version 3 (or 4?) of farmOS.


Immutable Quantities

Make quantities immutable and enforce that a single quantity is referenced by at most one log.

Rational: This makes changes to quantities more atomic and guarantees that the log’s changed timestamp is always updated when one or more of its quantities are changed.

Soft Entity Deletion

Make entity deletion an admin only action and provide a soft-delete (a.k.a. tombstone) mechanism for regular users (farm_manager, farm_worker). The logical choice here seems to be introducing deleted as a new status value - in addition to active and archived. (I’m open to other ideas - such as a dedicated boolean field too.)

Rational: This makes it easier for API clients to determine why an entity no longer “exists” - i.e. replication issue, database rollback, actual deletion, etc. It also makes data-loss easier to avoid in the case of a rogue user - i.e. rather than needing to get the data from a recent backup, it just becomes a matter of rolling the entity/entities back to an earlier - not “deleted” - revision.

Next Steps:

On a recent call I remember we talked about maybe having a more formal proposal mechanism - like PEP. “farmOS Enhancement Proposals” (FEP) anyone :nerd_face:?

I’d be happy to pilot such a mechanism if there’s interest… regardless of that I’d welcome any/all feedback on the above proposals.


Love both of these proposals @Symbioquine! Thanks for getting the conversation started. :slight_smile:

Yes!! :smile:

At the risk of bikeshedding… “FIP” is another option (“improvement” vs “enhancement”, eg: BIPs). Either way! I love the idea of formalizing this process for core data model changes moving forward.

This might allow us to remove our dependency on Entity Reference Revisions, and the extra complexity (eg: Issue #3267304) that it adds for API requests.

Feels like there will be a lot of code considerations with this change… curious to start thinking it all through…

This has been something I’ve wanted to see for a long time. :+1:

It will also require a fair bit of thought and extra logic to hide “deleted” status entities throughout the UI (and API?)


Thanks for the enthusiasm!


Yeah, I’m thinking it might not be too bad if we use the permission system…

Okay, I’ll bite…

  • GIIFT: Great Idea to Improve farmOS Today
  • FIELD: farmOS Immediate Enhancement Lightweight (Design|Draft)
  • FEAR: farmOS Enhancement Action Recommendation
  • FBI: farmOS Betterment Idea
1 Like

I think we’ll need to start a commission to decide what makes the most sense. /s :rofl:


Curious to understand how this helps with complexity… removing ERR would be nice, but do we create something more complex in its place? Right now to modify a quantity you must update the log.quantity revision_id after modifying the quantity entity. With this proposal you would need to create a new quantity as a “copy” of the “old” quantity with intended changes, remove the old quantity from the log.quantity field, and add the new quantity to log.quantity. Does that sound right?

1 Like

I was only referring to the extra “API surface complexity” that the ERR module adds by requiring the revision ID be specified in addition to the entity ID. That is an outlier in terms of the rest of our data model. Only requiring the entity ID would bring it in line with everything else, but there’s a lot more complexity added in other code to enforce immutability I agree. Whether or not that’s justified is up for discussion.

Quick note for future reference/detail: @paul121 and I were discussing in chat about some boilerplate PHP methods on the Asset/Log/(others?) entity type classes like getName() and getOwner() that might be worth deprecating in 2.x and removing in 3.x. They were created initially because it’s standard practice in custom Drupal entity types, but they aren’t really necessary and aren’t really justified - we could reduce the API surface a bit by removing them. Plus the getOwner() field is misleading… it returns the uid of the entity, not the owner field values that we add via the farm_owner module.


That’s definitely what I was suggesting - though typically some convenience mechanism would be provided in the write parts of the API to simplify doing so.

Thanks for pointing this out @paul121! I’ll need to play with it a bit more, but I think this actually may address most of my motivation for that part of this proposal.


  • That this guarantees that all well-formed quantity views/calculations will never see a partially modified set of quantities
  • That this guarantees that the log changed timestamp will always be updated when any quantity associated with the log is changed

Given the above, I think the only bit of this proposal regarding quantities left would be to enforce that a single quantity entity can’t be re-used for multiple logs.

Yeah, I’m not stuck on it. There’s a lot to be said for leveraging existing platform patterns, even if we might build it differently ourselves otherwise.


Is farmOS currently making use of the Published boolean for Quantities?

1 Like

No, quantities are their own entity type, and they don’t have a concept of “published”. farmOS doesn’t use Drupal node or comment entities for anything currently.

The available quantity attributes and relationships are described here: Quantities | farmOS

I suggest that if something is not removed from the database, it should not be called “deleted” - brainstorming around alternatives:


FYI I started a meta issue to track all the breaking changes we might want to propose/consider for farmOS 3.x: [META] farmOS 3.x Breaking Changes [#3347412] |

In my humble opinion, being new to FarmOS but having a long stance as a farmer trying to go digital, I have to say that a farm manager or dedicated farm worker would like to see a button labeled [delete] associated to such user function.

Farmers are radical in regard to the hard facts of life. For example, when they hung a sheep for eating, they have “killed” the sheep, not “archived” it. Therefore, they would like to press a button labeled [dead] [killed] [shot] or, close enough, [deleted], reserving [archived] for when declaring they have put its carcass in the freezer only :slight_smile:

Beyond joke, archived signifies to me that the thing is still there, somewhere. When a farm manager or diligent farm worker erases an asset because the flood took it away or because it was a mistake entry all together, they want to press the sure [delete] button.

For programmers, the action behind the label could be called soft delete, archived, or whatever the committee votes the best option. But I propose the UI label should be hard and clear of doubts —for it was done and recorded as such.


I’m a Beef farmer and i disagree with a lot of that.
I don’t think animals sold or slaughtered should be considered deleted, there are a few reasons why an animal needs to remain in an achieved state, such as:

  1. Compliance, records such as drugs given to the animal post termination needed for Inspectors.
  2. Lineage, animals used in breeding still have relationships with animals still on farm.
  3. Profit monitoring, weights prices for animals sold remain important.

Perhaps better language could be used for a UI button to Archive, but I believe the current mechanism is universal to all Asset types, so slaughter/kill might not make sense to a Tillage/veg farmers assets. Also slaughter is not always the right answer for a Livestock farmer either, it could be Slaughtered / Sold / Dropped Dead or even only temporarily archived in the case of Contract Rearing or simply an animal sold and bought back in future.

There is currently a delete Asset option (which can remove an Asset created in error)
Archive Asset is different and better describes an Asset that did exist but is no longer on farm.

Personally I think there is room for a few additional Log types, including Animal Death, and Animal Sales, and Animal Purchases and I have added these to my own self hosted instance through a custom module. Also @wotnak has made a nice termination module which can be used to make logs terminating (ie logs can archive the asset when they are created)


Hi Ed,

I agree 100% with what you said above (I am learning here)

I am interested in the custom module you developed for your self hosted beef farm instance. Perhaps there is room for same-industry farmers to collaborate in building modules such as yours, specific for a particular industry.


Always happy to share and/or collaborate, not an expert myself but getting to grips with the ins and outs thanks to the help I have received here.

Not much development needed to create new log types, Its a cut paste and minor modification of existing types. If you are self hosting your own farmOS instance make sure to have a separate Dev instance for experimenting with before commiting anything to your production instance.

Feel free to start a new topic to discuss what you’d like to achieve or just add to any relevant threads already started.