From 3d01d756657beae955cbbcef23373bb66d35bbf2 Mon Sep 17 00:00:00 2001 From: Arnaud Levy <contact@arnaudlevy.com> Date: Thu, 16 Feb 2023 15:38:23 +0100 Subject: [PATCH] wip --- .../javascripts/admin/commons/association.js | 12 +++-- .../websites/connections_controller.rb | 21 +++++++++ .../admin/connection_controller.rb | 26 ---------- app/models/communication/website.rb | 11 ++++- .../communication/website/connection.rb | 32 +++++++++++++ .../communication/website/with_connections.rb | 47 +++++++++++++++++++ app/models/concerns/with_connections.rb | 45 ------------------ .../concerns/with_simple_dependencies.rb | 21 +++++++++ .../show/special_pages/_organization.html.erb | 17 ++----- config/routes.rb | 2 - config/routes/admin/communication.rb | 1 + ...ation_websites_university_organizations.rb | 5 ++ ...reate_communication_website_connections.rb | 12 +++++ db/schema.rb | 26 ++++++---- .../communication/website/connections.yml | 39 +++++++++++++++ .../communication/website/connection_test.rb | 33 +++++++++++++ 16 files changed, 250 insertions(+), 100 deletions(-) create mode 100644 app/controllers/admin/communication/websites/connections_controller.rb delete mode 100644 app/controllers/admin/connection_controller.rb create mode 100644 app/models/communication/website/connection.rb create mode 100644 app/models/communication/website/with_connections.rb delete mode 100644 app/models/concerns/with_connections.rb create mode 100644 app/models/concerns/with_simple_dependencies.rb create mode 100644 db/migrate/20230216125347_remove_join_table_communication_websites_university_organizations.rb create mode 100644 db/migrate/20230216125515_create_communication_website_connections.rb create mode 100644 test/fixtures/communication/website/connections.yml create mode 100644 test/models/communication/website/connection_test.rb diff --git a/app/assets/javascripts/admin/commons/association.js b/app/assets/javascripts/admin/commons/association.js index c6bf81a8f..684b2255f 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 000000000..6dd7d8b2d --- /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 9fea69046..000000000 --- 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 680179780..8765a5d6d 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 000000000..425d0594f --- /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 000000000..8611f960d --- /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 6a2dc5fa7..000000000 --- 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 000000000..947db25b6 --- /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 c8a5b8ba8..ed9ed4035 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 93828e78c..4677d2123 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 6f71dbe89..dd59d972f 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 000000000..53975509b --- /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 000000000..92e7ca166 --- /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 0cb49100e..9783a3803 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 000000000..4627fe230 --- /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 000000000..8a13781a2 --- /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 -- GitLab