achempion

achempion

Hi,

My background is many years of ruby development. I was introduced to
Elixir couple of years ago and since then use it very often as it is
“go to” language for all my projects.

One main difference with ruby ecosystem for me is elixir is more
explicit. You have to define aliases, you have to import all required
functions and so on.

Although I like explicitness, I think in some cases it may slow down a
pace. As an example, often you need to check something in a database
in your console.

In order to do that with Ecto, you have do all imports, then you have
to remember all aliases for schemas and namespaces with context names.

I miss the ActiveRecord where you could write
User.last or User.find_by(email: "email").posts.

With Ecto you have to explicitly preload associations, import helper
functions and so on.

I’ve riched the point when I think about writing some wrapper/helper
which will load on console initialization and will define all aliases
in advance and automatically load associations on method calls.

I would like to know am I alone with this need and is it really an
issue. Maybe I need to have more experience with Ecto when I got used
to write all aliases/includes/preload every time I want to hack in a
console.

Thank you for any feedback on this topic.

Showing Posts 15 to 6

LostKobrakai

LostKobrakai

defmodule MyApp.Explore do
  defmacro __using__(_) do
    quote do
      alias App.Repo
      alias App.UserContext.User
      import Ecto.Query
    end
  end
end

and then you only need to call use MyApp.Explore whenever you need to do something with your data.

edisonywh

edisonywh

That’s what we are telling you though, you can have an .iex.exs that gets automatically loaded into your IEx sessions, so you don’t need to retype them every time.

achempion

achempion OP

Well, to be more precise, here is full example what I need to type every time I launch new session in order to achieve something similar to ActiveRecord

alias App.Repo
alias App.UserContext.User
import Ecto.Query

User |> where(email: "email") |> preload(:posts) |> Repo.one()

and I need to do it every time I want to work with a data. If I want to explore Post I have to write one more alias, every time I start new session.

Compare it to User.find_by(email: "email").posts and it’s just a short example. In real world it quickly adds up.

User.admin.first.posts.active.published.update_all(published: false)

Imagine how much typing required with Ecto. You have to alias: User, UserContext, Post, PostContext. You have to quickly remember context names as well for a schemas.

It requires lots of effort to write something quickly in console.

On the other hand, in a project code it really isn’t an issue, because you can write much faster with code editor and most aliases are already here. Also, you need to write custom queries much less often than when you’re hacking in a console.

al2o3cr

al2o3cr

To nitpick, this isn’t quite the same thing - this returns a User with posts preloaded, the other returns a list of Posts.

To nitpick moar, this does the same number of queries - Ecto does the preloads separately unless the query requires them to be done together explicitly with [posts: p] and a join.

Also beware blindly optimizing for “number of queries” - forcing a single query could be expensive if there are many posts and User is a wide schema, since it will include the user columns in every result row.

fuelen

fuelen

Both variants will do two separate queries.

hauleth

hauleth

Well, in this case I would prefer:

User |> where(email: "email") |> preload(:posts) |> Repo.one()

As it can reduce amount of queries and round trips.

al2o3cr

al2o3cr

It’s definitely possible to write these in comparably-short ways, once you’ve done import Ecto.Query:

User |> order_by(desc: :id) |> limit(1) |> Repo.one()

and

Repo.get_by(User, email: "email") |> Ecto.assoc(:posts) |> Repo.all()

These assume you have your schema and repo aliased in, but that isn’t required - full names will work just as well.

fuelen

fuelen

Exactly this implementation - no, it is in our todo list. In production, we use simplified version of it. Composite is an enhanced version after real production experience and a lot of local code reviews.

edisonywh

edisonywh

Oh hey that’s really similar indeed! I haven’t seen your library anywhere, the only similar ones I’ve found were TokenOperator & QueryBuilder.

That’s pretty cool! Good sign that the idea isn’t entirely out of whack :slight_smile: Have you been using it in prod & have you found any issues?

fuelen

fuelen

Wow, I created a library with very similar API called Composite (Composite - a library for writing dynamic queries) which allows to handle a lot of complex cases.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New
marciol
It would be helpful to have a list of companies worldwide that hire engineers without prior experience in Elixir. Often, it can be quite ...
New
Null-logic-0
What IDE or editor are you using for Elixir development? Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New

Other Trending Topics Top

marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews