Hey, everybody,
How to create a periodic task (performed once a day) that creates new meetings among all those who want to and have not yet met.
schema "users" do
field :email, :string
field :name, :string
field :surname, :string
field :is_status, :boolean, default: true
timestamps()
has_many :meetup1, Meetup, foreign_key: :meetuper1
has_many :meetup2, Meetup, foreign_key: :meetuper2
end
-------
schema "meetups" do
field :met_at, :naive_datetime
field :users, {:array, :integer}, virtual: true
field :meetuper1_rating, :integer
field :meetuper2_rating, :integer
field :average_rating, :float
timestamps()
belongs_to :user1, User, foreign_key: :meetuper1
belongs_to :user2, User, foreign_key: :meetuper2
end
You need to write query that creates cross-join between all people that hasn’t meet (beware that this will be quite expensive). Then create new entry for each resulting row.
After that write that as a script/function and run it using Cron or similar utility once a day.
I wrote a helper abtraction for that called Periodic. It is included in the parent library. See this docs section for details on fixed scheduling. I also wrote about periodic execution in more details in this blog post.
Note that the implementation described there basically generates lots of candidate solutions and searches for the best, so it won’t be efficient in terms of minimizing computation. This might or might not be a good approach for your task, depending on your constraints and goals.
As long as the “wish to meet” is an explicit action from the user, you can avoid the cross-join that @hauleth correctly indicated as expensive by modeling the wish of users to meet with each other with a join table.
You could even reuse your meetups table, adding a boolean column that indicates whether a meetup was already scheduled, or it is just a “wish”. If you always sort the foreign keys meetuser1 and meetuser2 in your meetups (say by enforcing that meetuser1 is the one with the smallest ID), then you can enforce uniqueness of meetups between specific people by adding a unique index on [meetuser1, meetuser2].
Then, you can run a periodic job with something like Oban that would select a maximum number of meetups still in “wish” state, and actually schedule them.