Skip to content

Potential .embed_as change #15

Closed

Description

@BigBoyBarney

Hi!
Thank you for this shard, it's super cool!

I just ran into an issue with Drift.embed_as, where the following didn't work:

module Mayling::Database::Schema
  Drift.embed_as "migrations", "./", dir: __DIR__

  def self.sync
    migrator = Drift::Migrator.new(Mayling::DATABASE, context: migrations)
    migrator.apply!
  end
end

After taking a quick look at the source code, I realised that the macro is creating a method, so prepending self. solved it. This is also briefly mentioned in the readme.

However, it got me thinking. This kind of requires the user to pay attention to where the macro is written, and name it accordingly, potentially ending up in a mismatch with the migrator.

In src/drift/embed.cr, the following addition would do this automatically.

module Drift
  macro embed_as(name, path, dir = __DIR__)
    {% begin %}

    {% if @type.name != "main" %}
      {% method_name = "self.#{name.id}" %}
    {% else %}
      {% method_name = name.id %}
    {% end %}

    def {{ method_name.id }} : Drift::Context
      ctx = Drift::Context.new

      {{ run("./support/migrations_loader.cr", path, dir) }}

      ctx
    end
    {% end %}
  end
end

It would essentially prepend self. if the macro is called inside a module.
This would obviously be a breaking change, but I'd like to hear your thoughts :)

Thanks again for the shard!

Activity

  1. luislavena commented on Jul 13, 2025

    @luislavena
    Owner

    Hello @BigBoyBarney, thank you for trying out Drift and your feedback.

    Indeed this is briefly mentioned in the README, but perhaps is worth a better clarification to explain it's usage? User will be getting a compile error when the method that is referenced is not found.

    I'm concerned on making implicit decisions on behalf of the users. One example of that is how I personally use Drift: I use a module as an interface (with abstract methods) and have different classes implementing it, to allow me tweak the context on which the database is loaded/migrated, yet have the same migration references.

    While it obviously will be a breaking change, I'm more biased towards explicit over implicit behaviors.

    Once again, thank you for your feedback. Leaving this open to think it through.

    Cheers.

  2. BigBoyBarney commented on Jul 13, 2025

    @BigBoyBarney
    Author

    I completely understand, I generally prefer explicit over implicit too, especially when it's hidden behind a macro.

    You make a very good point. I never really thought about the interface way of doing it, and just assumed that self. is mandatory when in a module, as that's how I personally use it. This additional macro would not allow for the interface usage I think, so that's definitely not ideal.

    Maybe a slightly longer readme explanation on its correct usage with a potential example would be more than enough.

    Thank you!

  3. added 2 commits that reference this issue on Jan 20, 2026
    23e64f3
    d07e159
  4. luislavena commented on Jan 20, 2026

    @luislavena
    Owner

    @BigBoyBarney would you mind looking at #29 for the updated documentation to see if that provides enough details?

    Cheers.

  5. BigBoyBarney commented on Jan 20, 2026

    @BigBoyBarney
    Author

    Yep, that's perfect. Clear as day, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions