Many_to_many and has_many in between two same schemas?

Hi everyone,

I have User and Event schemas. User can attend many Events, Event can have many attendees.

On top of that, a User can also organize Events.

So I think I need to have many_to_many association between User and Event. But shall I have also has_many / belongs_to association between them at the same time? Is that even possible and is it the right way to do it?

Here’s my idea of the schemas:

defmodule User do
  use Ecto.Schema

  schema "users" do
    many_to_many :events, Event, join_through: UserEvent
    has_many :events, Event # doesn't this clash with the above in any way?
  end
end

defmodule Event do
  use Ecto.Schema

  schema "events" do
    many_to_many :attendees, User, join_through: UserEvent
    belongs_to :organizer, User
    # is it possible and advisable to use :attendees and :organizer here, instead of :users and :user ?
  end
end

defmodule UserEvent do
  use Ecto.Schema

  @primary_key false
  schema "users_events" do
    belongs_to :attendee, User # should it be :attendee or :user ?
    belongs_to :event, Event
    timestamps
    # maybe other data
  end

  # this changeset def is taken from https://hexdocs.pm/ecto/Ecto.Schema.html#many_to_many/3-join-schema-example
  def changeset(struct, params \\ %{}) do
    struct
    |> Ecto.Changeset.cast(params, [:user_id, :event_id])
    |> Ecto.Changeset.validate_required([:user_id, :event_id])
    # Maybe do some counter caching here! - what do they mean by 'counter caching' in the guides, please?
  end
end

My additional questions coming to my mind are:

  • can I use :attendees and :organizer in events schema to make things less confusing?
  • what does the ‘counter caching’ above mean? doesn’t that make a mess elsewhere?
  • as I’m still a newbie, is this doable via generators? maybe phx.gen.html for User and Event and then just phx.gen.schema for the UserEvent join table?
  • am I horribly wrong and missing some crucial component here?

Thank you so much!!