Skip to content

37 feature use module attributes to map events to action names#44

Merged
vincentvanbush merged 13 commits intomainfrom
37-feature-use-module-attributes-to-map-events-to-action-names
Dec 4, 2025
Merged

37 feature use module attributes to map events to action names#44
vincentvanbush merged 13 commits intomainfrom
37-feature-use-module-attributes-to-map-events-to-action-names

Conversation

@vincentvanbush
Copy link
Contributor

@vincentvanbush vincentvanbush commented Nov 27, 2025

Pull Request

Description

In addition to the existing event_mapping/0 callback, introduces the @permit_action module attribute to annotate LiveView event handlers with the corresponding Permit action name.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Performance improvement
  • Code refactoring
  • Test improvements
  • CI/CD improvements

Related Issues

Closes #37

Changes Made

Testing

Tests added for both Ecto and non-Ecto (loader-based) resolution in LiveViews. Also tested manually with a companion app.

Test Environment

  • Elixir version: 1.19.4
  • OTP version: 28
  • Phoenix version: 1.8.1
  • LiveView version: 1.1.17
  • Database (if applicable): PostgreSQL 15

Test Cases

  • All existing tests pass
  • New tests added for new functionality at appropriate levels
  • Manual testing performed
  • Controller integration tests (if applicable)
  • LiveView integration tests (if applicable)
  • Router integration tests (if applicable)

Test Commands Run

# List the commands you ran to test
mix test
MIX_ENV=test mix credo
MIX_ENV=test mix dialyzer

Documentation

  • Updated README.md (if applicable)
  • Updated documentation comments (with examples for new features)
  • Updated CHANGELOG.md (if applicable)
  • Updated controller/LiveView usage examples (if applicable)

Code Quality

  • Code follows the existing style conventions
  • Self-review of the code has been performed
  • Code has been commented, particularly in hard-to-understand areas
  • No new linting warnings introduced
  • No new Dialyzer warnings introduced
  • Follows Phoenix and LiveView conventions

Phoenix/LiveView Specific

  • Controller changes properly handle conn state
  • LiveView changes properly handle socket state
  • Router integration works correctly
  • Error handling follows Phoenix patterns
  • Authorization flows work as expected

Backward Compatibility

  • This change is backward compatible
  • This change includes breaking changes (please describe below)
  • Migration guide provided for breaking changes

Breaking Changes

Performance Impact

  • No performance impact
  • Performance improvement
  • Potential performance regression (please describe)

Performance Notes

Security Considerations

  • No security impact
  • Security improvement
  • Potential security impact (please describe)

Additional Notes

Screenshots/Examples

      @impl true
      @permit_action :update
      def handle_event("save", %{"article" => article_params}, socket) do
        article = socket.assigns.loaded_resource

        case MyApp.update_article(article_params) do
          # ...
        end
      end

Checklist

  • I have read the Contributing Guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Reviewer Notes


@vincentvanbush vincentvanbush linked an issue Nov 27, 2025 that may be closed by this pull request
3 tasks
@moduledoc false

def __on_definition__(env, _kind, :handle_event, args, _guards, _body) do
event_name = args |> List.first()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
event_name = args |> List.first()
event_name = List.first(args)

@callback unauthorized_message(PhoenixTypes.socket(), map()) :: binary()
@callback event_mapping() :: map()
@doc ~S"""
For events that do not carry an `"id"` param (e.g. updating a record with form data), determines whether to reload the record before each event authorization.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

case unquote(opts[:reload_on_event?]) do
fun when is_function(fun) -> fun.(action, socket)
nil -> true
other -> other
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: What can be other? 🤔 Maybe it would be better to tighten the possible callbacks?

@impl true 
def reload_on_event?(action, socket) do
  case unquote(opts[:reload_on_event?]) do
    fun when is_function(fun, 2) -> fun.(action, socket)
    bool when is_boolean(bool) -> bool
    nil -> true
    other -> raise ArgumentError, "expected :reload_on_event? option to be a boolean or a 2-arity function, got: #{inspect(other)}"
  end
end

Copy link
Contributor Author

@vincentvanbush vincentvanbush left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q: What can be other? 🤔 Maybe it would be better to tighten the possible callbacks?

@impl true 
def reload_on_event?(action, socket) do
  case unquote(opts[:reload_on_event?]) do
    fun when is_function(fun, 2) -> fun.(action, socket)
    bool when is_boolean(bool) -> bool
    nil -> true
    other -> raise ArgumentError, "expected :reload_on_event? option to be a boolean or a 2-arity function, got: #{inspect(other)}"
  end
end

It can also be false, so the raising pattern must be preceded by that.

@vincentvanbush vincentvanbush merged commit 4d9379d into main Dec 4, 2025
73 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Use module attributes to map events to action names

2 participants