diff --git a/app/assets/javascripts/admin/commons/association.js b/app/assets/javascripts/admin/commons/association.js
index c6bf81a8fb6906951ee627ae01e7f69db7184634..684b2255f082ae0b4a6a7802d6596eef329620db 100644
--- a/app/assets/javascripts/admin/commons/association.js
+++ b/app/assets/javascripts/admin/commons/association.js
@@ -3,12 +3,16 @@ $(function () {
     'use strict';
     $('input.autocomplete')
         .on('railsAutocomplete.select', function ($event, data) {
-            var connect = $event.target.dataset.connect,
-                id = data.item.id,
-                url = connect.replace(':dependency_id', id);
+            var type = $event.target.dataset.type,
+                target = $event.target.dataset.target,
+                id = data.item.id;
             $.ajax({
                 type: 'POST',
-                url: url
+                url: target,
+                data: {
+                    object_id: id,
+                    object_type: type
+                }
             }).done(function () {
                 location.reload();
             });
diff --git a/app/controllers/admin/communication/websites/connections_controller.rb b/app/controllers/admin/communication/websites/connections_controller.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6dd7d8b2d68e24bdbfdd66aeac5c7d7d934113e1
--- /dev/null
+++ b/app/controllers/admin/communication/websites/connections_controller.rb
@@ -0,0 +1,21 @@
+class Admin::Communication::Websites::ConnectionsController < Admin::Communication::Websites::ApplicationController
+  before_action :load_object
+
+  def create
+    @website.connect @object
+    head :ok
+  end
+  
+  def destroy
+    @website.disconnect @object
+    redirect_back(fallback_location: [:admin, @object])
+  end
+
+  protected
+
+  def load_object
+    object_type = params[:object_type]
+    object_id = params[:object_id]
+    @object = object_type.constantize.find object_id
+  end
+end
\ No newline at end of file
diff --git a/app/controllers/admin/connection_controller.rb b/app/controllers/admin/connection_controller.rb
deleted file mode 100644
index 9fea690461d994bb7d6f983b2ec7ad73ef45e11e..0000000000000000000000000000000000000000
--- a/app/controllers/admin/connection_controller.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-class Admin::ConnectionController < Admin::ApplicationController
-  before_action :load_data
-
-  def connect
-    @object.connect @dependency
-    head :ok
-  end
-  
-  def disconnect
-    @object.disconnect @dependency
-    redirect_back(fallback_location: [:admin, @object])
-  end
-
-  protected
-
-  def load_data
-    @object_type = params[:object_type]
-    @object_id = params[:object_id]
-    @object = @object_type.constantize.find @object_id
-    # TODO vérifier l'université
-    @dependency_type = params[:dependency_type]
-    @dependency_id = params[:dependency_id]
-    @dependency = @dependency_type.constantize.find @dependency_id
-    # TODO vérifier l'université
-  end
-end
\ No newline at end of file
diff --git a/app/models/communication/website.rb b/app/models/communication/website.rb
index 680179780b558ebade9d891e95dba878095b073b..8765a5d6de87e0118ed82b3527baa667e342b427 100644
--- a/app/models/communication/website.rb
+++ b/app/models/communication/website.rb
@@ -41,6 +41,7 @@ class Communication::Website < ApplicationRecord
   include WithConfigs
   include WithConnections
   include WithDependencies
+  include WithSimpleDependencies
   include WithGit
   include WithGitRepository
   include WithImport
@@ -62,8 +63,6 @@ class Communication::Website < ApplicationRecord
                           foreign_key: 'communication_website_id',
                           association_foreign_key: 'language_id'
 
-  has_connections University::Organization
-
   validates :languages, length: { minimum: 1 }
   validate :languages_must_include_default_language
 
@@ -85,6 +84,14 @@ class Communication::Website < ApplicationRecord
     "data/website.yml"
   end
 
+  def direct_dependencies
+    pages +
+    posts + 
+    categories +
+    menus +
+    [about]
+  end
+
   def git_dependencies(website)
     dependencies = [
       self,
diff --git a/app/models/communication/website/connection.rb b/app/models/communication/website/connection.rb
new file mode 100644
index 0000000000000000000000000000000000000000..425d0594f2bea1314ef9f5a2553e5d12d64db77a
--- /dev/null
+++ b/app/models/communication/website/connection.rb
@@ -0,0 +1,32 @@
+# == Schema Information
+#
+# Table name: communication_website_connections
+#
+#  id            :uuid             not null, primary key
+#  object_type   :string           not null, indexed => [object_id]
+#  source_type   :string           indexed => [source_id]
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  object_id     :uuid             not null, indexed => [object_type]
+#  source_id     :uuid             indexed => [source_type]
+#  university_id :uuid             not null, indexed
+#  website_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_connections_on_object         (object_type,object_id)
+#  index_communication_website_connections_on_source         (source_type,source_id)
+#  index_communication_website_connections_on_university_id  (university_id)
+#  index_communication_website_connections_on_website_id     (website_id)
+#
+# Foreign Keys
+#
+#  fk_rails_728034883b  (website_id => communication_websites.id)
+#  fk_rails_bd1ac8383b  (university_id => universities.id)
+#
+class Communication::Website::Connection < ApplicationRecord
+  belongs_to :university
+  belongs_to :website
+  belongs_to :object, polymorphic: true
+  belongs_to :source, polymorphic: true, optional: true
+end
diff --git a/app/models/communication/website/with_connections.rb b/app/models/communication/website/with_connections.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8611f960de381bec652e25e809a91b798b1e53cb
--- /dev/null
+++ b/app/models/communication/website/with_connections.rb
@@ -0,0 +1,47 @@
+module Communication::Website::WithConnections
+  extend ActiveSupport::Concern
+
+  included do
+    has_many  :connections
+    has_many  :connected_organizations,
+              -> { distinct },
+              through: :connections,
+              source: :object,
+              source_type: 'University::Organization'
+  end
+
+  def clean_connections!
+    start = Time.now
+    connect self
+    connections.where('updated_at < ?', time).destroy_all
+  end
+
+  def connect(object, source = nil)
+    connect_object object, source
+    return unless object.respond_to?(:simple_dependencies)
+    object.simple_dependencies.each do |dependency|
+      connect_object dependency, source
+      connect_object dependency, object # Faut-il la double connexion ?
+    end
+  end
+
+  # TODO pas pensé
+  def disconnect(object, source = nil)
+    disconnect_object object, source
+    return unless object.respond_to?(:simple_dependencies)
+    object.simple_dependencies.each do |dependency|
+      disconnect_object dependency, source
+      disconnect_object dependency, object # Faut-il la double connexion ?
+    end
+  end
+
+  protected
+
+  def connect_object(object, source)
+    connections.where(university: university, object: object, source: source).first_or_create
+  end
+
+  def disconnect_object(object, source)
+    connections.where(university: university, object: object, source: source).destroy_all
+  end
+end
\ No newline at end of file
diff --git a/app/models/concerns/with_connections.rb b/app/models/concerns/with_connections.rb
deleted file mode 100644
index 6a2dc5fa73fc904c81a5e6c29b0433b90851d3c2..0000000000000000000000000000000000000000
--- a/app/models/concerns/with_connections.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-module WithConnections
-  extend ActiveSupport::Concern
-
-  included do
-    def self.has_connections(klass)
-      # university_organizations
-      relation = relation_name klass
-      # University::Organization
-      class_name = klass.to_s
-      # :communication_website_id
-      foreign_key = "#{self.to_s.underscore.gsub('/', '_')}_id".to_sym
-      # :university_organization_id
-      association_foreign_key = "#{klass.to_s.underscore.gsub('/', '_')}_id".to_sym
-      has_and_belongs_to_many relation,
-                              class_name: class_name,
-                              foreign_key: foreign_key,
-                              association_foreign_key: association_foreign_key
-
-    end
-
-    protected
-  
-    # University::Organization -> university_organizations
-    def self.relation_name(klass)
-      klass.to_s.underscore.gsub('/', '_').pluralize.to_sym
-    end
-  end
-
-  def connect(dependency)
-    relation = relation(dependency)
-    return if dependency.in?(relation)
-    relation << dependency
-  end
-  
-  def disconnect(dependency)
-    relation(dependency).delete dependency
-  end
-
-  protected
-  
-  def relation(instance)
-    relation_name = self.class.relation_name instance.class
-    send relation_name
-  end
-end
\ No newline at end of file
diff --git a/app/models/concerns/with_simple_dependencies.rb b/app/models/concerns/with_simple_dependencies.rb
new file mode 100644
index 0000000000000000000000000000000000000000..947db25b636b64c26640d22c3369dccefdd6cc91
--- /dev/null
+++ b/app/models/concerns/with_simple_dependencies.rb
@@ -0,0 +1,21 @@
+module WithSimpleDependencies
+  extend ActiveSupport::Concern
+
+  # Cette méthode doit être définie dans chaque objet, 
+  # et renvoyer un tableau de ses références directes.
+  # Jamais de référence indirecte !
+  # Elles sont gérées récursivement
+  def direct_dependencies
+    []
+  end
+
+  def simple_dependencies(list = [])
+    direct_dependencies.each do |dependency|
+      next if dependency.in?(list)
+      list << dependency
+      next unless dependency.respond_to?(:simple_dependencies)
+      list += dependency.simple_dependencies(list)
+    end
+    list
+  end
+end
\ No newline at end of file
diff --git a/app/views/admin/communication/websites/pages/show/special_pages/_organization.html.erb b/app/views/admin/communication/websites/pages/show/special_pages/_organization.html.erb
index c8a5b8ba87b9494d259bc46162166c3199fbe291..ed9ed4035907ae9bc66ac5a06f0cd2ac18434778 100644
--- a/app/views/admin/communication/websites/pages/show/special_pages/_organization.html.erb
+++ b/app/views/admin/communication/websites/pages/show/special_pages/_organization.html.erb
@@ -1,5 +1,5 @@
 <%
-@organizations = @website.university_organizations.ordered.page params[:page]
+@organizations = @website.connected_organizations.ordered.page params[:page]
 %>
 <%= osuny_panel University::Organization.model_name.human(count: 2) do %>
   <%= simple_form_for :association, class_name: 'association' do |f| %>
@@ -10,12 +10,8 @@
                 placeholder: t("extranet.experiences.search_organization"),
                 input_html: {
                   data: {
-                    connect: admin_connect_path(  lang: nil, 
-                                                  website_id: nil,
-                                                  object_type: @website.class, 
-                                                  object_id: @website.id, 
-                                                  dependency_type: University::Organization,
-                                                  dependency_id: ':dependency_id')
+                    type: 'University::Organization',
+                    target: admin_communication_website_connections_path(lang: nil)
                   }
                 }
                 %>
@@ -26,12 +22,7 @@
         <tr>
           <td><%= link_to organization, [:admin, organization] %></td>
           <td><%= link_to 'Déconnecter', 
-                          admin_disconnect_path(lang: nil, 
-                                                website_id: nil,
-                                                object_type: @website.class, 
-                                                object_id: @website.id, 
-                                                dependency_type: organization.class,
-                                                dependency_id: organization.id),
+                          admin_communication_website_connection_path(id: 'no-id', object_id: organization.id, object_type: organization.class),
                           class: button_classes_danger,
                           method: :delete %></td>
         </tr>
diff --git a/config/routes.rb b/config/routes.rb
index 93828e78c326756a7fb1ea53047027dfe264f9ed..4677d21232310cf3b10e6587ef340602c5d4b9df 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -24,8 +24,6 @@ Rails.application.routes.draw do
       patch 'unlock' => 'users#unlock', on: :member
     end
     put 'theme' => 'application#set_theme', as: :set_theme
-    post 'connect/:object_type/:object_id/:dependency_type/:dependency_id' => 'connection#connect', as: :connect
-    delete 'disconnect/:object_type/:object_id/:dependency_type/:dependency_id' => 'connection#disconnect', as: :disconnect
     draw 'admin/administration'
     draw 'admin/communication'
     draw 'admin/education'
diff --git a/config/routes/admin/communication.rb b/config/routes/admin/communication.rb
index 6f71dbe89023ffd98121bbd10ab27be17da68965..dd59d972f3a57d607ee0905ef1d705f39ed0407d 100644
--- a/config/routes/admin/communication.rb
+++ b/config/routes/admin/communication.rb
@@ -10,6 +10,7 @@ namespace :communication do
       get :style
       get :analytics
     end
+    resources :connections, controller: 'websites/connections', only: [:create, :destroy]
     resources :pages, controller: 'websites/pages', path: '/:lang/pages' do
       collection do
         post :reorder
diff --git a/db/migrate/20230216125347_remove_join_table_communication_websites_university_organizations.rb b/db/migrate/20230216125347_remove_join_table_communication_websites_university_organizations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..53975509badd6e04f0cacdbabc4e7f32a1d8ecec
--- /dev/null
+++ b/db/migrate/20230216125347_remove_join_table_communication_websites_university_organizations.rb
@@ -0,0 +1,5 @@
+class RemoveJoinTableCommunicationWebsitesUniversityOrganizations < ActiveRecord::Migration[7.0]
+  def change
+    drop_table :communication_websites_university_organizations
+  end
+end
diff --git a/db/migrate/20230216125515_create_communication_website_connections.rb b/db/migrate/20230216125515_create_communication_website_connections.rb
new file mode 100644
index 0000000000000000000000000000000000000000..92e7ca1662e9a4c3d63cba788412223c67774d88
--- /dev/null
+++ b/db/migrate/20230216125515_create_communication_website_connections.rb
@@ -0,0 +1,12 @@
+class CreateCommunicationWebsiteConnections < ActiveRecord::Migration[7.0]
+  def change
+    create_table :communication_website_connections, id: :uuid do |t|
+      t.references :university, null: false, foreign_key: true, type: :uuid
+      t.references :website, null: false, foreign_key: {to_table: :communication_websites}, type: :uuid
+      t.references :object, null: false, type: :uuid, polymorphic: true
+      t.references :source, type: :uuid, polymorphic: true
+
+      t.timestamps
+    end
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0cb49100e6b4f8121e2250f8a456394adbd8b81e..9783a3803aabd51a9e0e242dc5c92cde1a3b67ac 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema[7.0].define(version: 2023_02_14_071223) do
+ActiveRecord::Schema[7.0].define(version: 2023_02_16_125515) do
   # These are extensions that must be enabled in order to support this database
   enable_extension "pgcrypto"
   enable_extension "plpgsql"
@@ -151,6 +151,21 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_14_071223) do
     t.index ["communication_website_post_id", "communication_website_category_id"], name: "post_category"
   end
 
+  create_table "communication_website_connections", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
+    t.uuid "university_id", null: false
+    t.uuid "website_id", null: false
+    t.string "object_type", null: false
+    t.uuid "object_id", null: false
+    t.string "source_type"
+    t.uuid "source_id"
+    t.datetime "created_at", null: false
+    t.datetime "updated_at", null: false
+    t.index ["object_type", "object_id"], name: "index_communication_website_connections_on_object"
+    t.index ["source_type", "source_id"], name: "index_communication_website_connections_on_source"
+    t.index ["university_id"], name: "index_communication_website_connections_on_university_id"
+    t.index ["website_id"], name: "index_communication_website_connections_on_website_id"
+  end
+
   create_table "communication_website_git_files", id: :uuid, default: -> { "public.gen_random_uuid()" }, force: :cascade do |t|
     t.string "previous_path"
     t.string "about_type", null: false
@@ -409,13 +424,6 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_14_071223) do
     t.index ["communication_website_id", "language_id"], name: "website_language"
   end
 
-  create_table "communication_websites_university_organizations", id: false, force: :cascade do |t|
-    t.uuid "communication_website_id", null: false
-    t.uuid "university_organization_id", null: false
-    t.index ["communication_website_id", "university_organization_id"], name: "website_organization"
-    t.index ["university_organization_id", "communication_website_id"], name: "organization_website"
-  end
-
   create_table "communication_websites_users", id: false, force: :cascade do |t|
     t.uuid "communication_website_id", null: false
     t.uuid "user_id", null: false
@@ -928,6 +936,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_14_071223) do
   add_foreign_key "communication_website_categories", "education_programs", column: "program_id"
   add_foreign_key "communication_website_categories", "languages"
   add_foreign_key "communication_website_categories", "universities"
+  add_foreign_key "communication_website_connections", "communication_websites", column: "website_id"
+  add_foreign_key "communication_website_connections", "universities"
   add_foreign_key "communication_website_git_files", "communication_websites", column: "website_id"
   add_foreign_key "communication_website_imported_authors", "communication_website_imported_websites", column: "website_id"
   add_foreign_key "communication_website_imported_authors", "universities"
diff --git a/test/fixtures/communication/website/connections.yml b/test/fixtures/communication/website/connections.yml
new file mode 100644
index 0000000000000000000000000000000000000000..4627fe2306344d56fa751f5c15c356593a05460b
--- /dev/null
+++ b/test/fixtures/communication/website/connections.yml
@@ -0,0 +1,39 @@
+# == Schema Information
+#
+# Table name: communication_website_connections
+#
+#  id            :uuid             not null, primary key
+#  object_type   :string           not null, indexed => [object_id]
+#  source_type   :string           indexed => [source_id]
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  object_id     :uuid             not null, indexed => [object_type]
+#  source_id     :uuid             indexed => [source_type]
+#  university_id :uuid             not null, indexed
+#  website_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_connections_on_object         (object_type,object_id)
+#  index_communication_website_connections_on_source         (source_type,source_id)
+#  index_communication_website_connections_on_university_id  (university_id)
+#  index_communication_website_connections_on_website_id     (website_id)
+#
+# Foreign Keys
+#
+#  fk_rails_728034883b  (website_id => communication_websites.id)
+#  fk_rails_bd1ac8383b  (university_id => universities.id)
+#
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  university: one
+  website: one
+  object: one
+  source: one
+
+two:
+  university: two
+  website: two
+  object: two
+  source: two
diff --git a/test/models/communication/website/connection_test.rb b/test/models/communication/website/connection_test.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8a13781a25ad6b4d428209c8f1a114f7d40cd42f
--- /dev/null
+++ b/test/models/communication/website/connection_test.rb
@@ -0,0 +1,33 @@
+# == Schema Information
+#
+# Table name: communication_website_connections
+#
+#  id            :uuid             not null, primary key
+#  object_type   :string           not null, indexed => [object_id]
+#  source_type   :string           indexed => [source_id]
+#  created_at    :datetime         not null
+#  updated_at    :datetime         not null
+#  object_id     :uuid             not null, indexed => [object_type]
+#  source_id     :uuid             indexed => [source_type]
+#  university_id :uuid             not null, indexed
+#  website_id    :uuid             not null, indexed
+#
+# Indexes
+#
+#  index_communication_website_connections_on_object         (object_type,object_id)
+#  index_communication_website_connections_on_source         (source_type,source_id)
+#  index_communication_website_connections_on_university_id  (university_id)
+#  index_communication_website_connections_on_website_id     (website_id)
+#
+# Foreign Keys
+#
+#  fk_rails_728034883b  (website_id => communication_websites.id)
+#  fk_rails_bd1ac8383b  (university_id => universities.id)
+#
+require "test_helper"
+
+class Communication::Website::ConnectionTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end