jj split is a gamechanger
#jj-vcs
jj split is a gamechanger
#jj-vcs
bsky.app/profile/jake...
This thread has some thoughts about implementing the `has_one_attached` and `has_many_attached` using built in Ecto associations.
The basic implementation can be seen in github.com/jakeprem/ect..., look at `EctoStorage.Migrations` and `EctoStorage.Attachments.*`. Right now in `EctoStorage.Schema` I'm just using Ecto's `belongs_to`, `has_one`, and `has_one` with `:through` but a custom association type should be possible too.
This setup should guarantee referential integrity while still allowing for generic attachment handling. It avoids having a join table per schema (no `posts_attachments`) or otherwise having to have extra setup for every schema that needs attachments.
Schemas in your app with attachments add a single foreign key to the ledger table per attachment type. e.g. a Post schema could have `cover_image_ledger_id` and `files_ledger_id`. Then any attachments you add have a foreign key to the ledger table as well.
Like when you have a `record_type` and `record_id` column to achieve polymorphism the database can't track that. You could deleted the referenced record, or you could break it by changing the type. If you use a setup with foreign keys, the database can guarantee the relational integrity.
Short answer is the way ActiveRecord (and ActiveStorage by extension) does polymorphism does not benefit from database reference guarantees. (See hexdocs.pm/ecto/polymor... for "official" Ecto reasoning). I think for wide adoption an Elixir storage solution would want to follow Ecto's patterns too.
I'll be speaking on Tuesday at 6PM ET as part of the Global Elixir Meetup (GEM) week. If you're in the Cincinnati area, join us in person at the Launch Scout office. If you can't make it, the event will be streamed. Details at globalelixirmeetups.com/event/cincin...
#elixirlang
I started working on a library for this. The key difference from ActiveStorage is using a ledger table rather than record_type/record_id columns for polymorphism. Otherwise I'd like to support roughly all of ActiveStorage. There's an MVP blog example.
github.com/jakeprem/ect...
Come join us for our Global Elixir Meetup! The Ohio edition will be on Tuesday, September 23rd at 6pm (EDT) with in person and online options. @brianmeeker.bsky.social will be sharing how to "Refurbish Your Creaky Test Suite"! Visit www.ohioelixir.com to signup.
#ElixirLang #GlobalElixirMeetups
Tip of the day (aka I wasted way too much time realizing this):
- Chrome device mode is buggy
- Tailscale serve makes sharing dev servers to mobile devices easy
- Phoenix Live Reload works across Tailscale connections
- Use this to test responsive design directly on devices
#ElixirLang #Tailscale
Shoutout to @vereis.com and @ivymarkwell.com for their work on this!
I’ve been looking for something like this since pglite was first announced!
Super cool!
If you don't immediately need strong uptime guarantees why not start with self hosting and point an uptime monitor at it?
Do you have the cluster + your router on a UPS already?
This is a great tip! We've added it to dev.exs before too to limit the override to only dev environments.
Just wrote a quick post on restarting Phoenix Playgrounds in Livebook. (e.g. to run multiple examples in a row). Check it out:
jakeprem.com/posts/easy-l...
#ElixirLang #Livebook
Ecto code showing a more conventional has many through approach: schema "posts" do belongs_to :photos_ledger, AttachmentLedger has_many :photos, through: [:photos_ledger, :attachments] end
The more conventional approach of `has_many, through:`:
1. Maintains database integrity with foreign keys
2. `Repo.preload(posts, :photos)` includes a query of the ledger table as well as the attachments table
3. `:through` associations are read only
An example Ecto migration showing that both fields still use foreign key references: create table(:attachments) do # ... add :attachment_ledger_id, references(:attachment_ledgers) end create table(:posts) do # ... add :photos_ledger_id, references(:attachment_ledgers) end
Pros of this approach:
1. Both fields still use a foreign key reference in the database
2. `Repo.preload(posts, :photos)` queries the attachments table directly rather than traversing the ledger table.
3. `Ecto.build_assoc/3` and related seem to work.
Elixir code describing an approach to has_many associations in Ecto using a ledger record: schema "posts" do belongs_to :photos_ledger, AttachmentLedger has_many :photos, Attachment, foreign_key: :attachment_ledger_id, references: :photos_ledger_id end iex> post = %Post{photos_ledger_id: 1} iex> Ecto.build_assoc(post, :photos, attrs) %Attachment{attachment_ledger_id: 1}
Experimenting with building a library with ActiveStorage-like functionality for Ecto.
Convince me this `has_many` usage is a bad idea?
#ElixirLang
Yep, exactly! It's a scheduling component, so when a user submits a form, it triggers `handle_params` which should reload the data so that whatever events they just saved show up. But I was never actually reloading the events haha
Sometimes the reason your LiveView isn't updating properly is because your code was never reloading the data in the first place.
Sometimes you spend 3 hours debugging LiveView change tracking with increasingly convoluted data refactors to confirm this fact.
Follow me for more #ElixirLang pro-tips.
I've been using Claude pretty extensively for Elixir work and I'm pretty happy with it. I think it was better than ChatGPT 4o, supported projects, and bigger context windows when I switched.
Biggest advantage though is the background color is more aesthetically pleasing than ChatGPT 😁
For most LiveView apps if you create a package.json NodeJS and Bun should be pretty interchangeable right?
I personally use Bun where I can but more developers will probably already have NodeJS installed.