diff --git a/.rubocop.yml b/.rubocop.yml index 980b6f08..5c2335f8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,18 +1,36 @@ +AllCops: + TargetRubyVersion: '2.5' + +Style/AsciiComments: + Enabled: false + Metrics/LineLength: Exclude: - 'db/schema.rb' - 'db/migrate/*.rb' + - 'app/models/site.rb' Metrics/AbcSize: Exclude: - 'db/schema.rb' - 'db/migrate/*.rb' + - 'app/models/site.rb' Metrics/MethodLength: Exclude: - 'db/schema.rb' - 'db/migrate/*.rb' + - 'app/models/site.rb' Metrics/BlockLength: Exclude: - 'config/initializers/devise.rb' + - 'db/schema.rb' + +Metrics/ClassLength: + Exclude: + - 'app/models/site.rb' + +Performance/TimesMap: + Exclude: + - 'app/models/site.rb' diff --git a/app/models/site.rb b/app/models/site.rb index e77f0849..3e86527d 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -2,20 +2,14 @@ # Un sitio es un directorio dentro del directorio de sitios de cada # Usuaria -class Site +class Site < ApplicationRecord + has_and_belongs_to_many :usuaries, class_name: 'Usuarie' + has_and_belongs_to_many :invitades, class_name: 'Usuarie', + join_table: 'invitades_sites' + attr_accessor :jekyll, :collections attr_reader :path - def inspect - "#" - end - - def initialize(jekyll:, path: nil) - @jekyll = jekyll - @path = path || @jekyll.config['source'] - @collections = {} - end - # Este sitio acepta invitadxs? def invitadxs? jekyll.config.fetch('invitadxs', false) @@ -68,13 +62,6 @@ class Site @layouts ||= @jekyll.layouts.keys.sort end - # Obtener el nombre del sitio - def name - @name ||= File.basename(@jekyll.config['source']) - end - alias id name - alias to_s name - def name_with_i18n(lang) [name, lang].join('/') end @@ -109,8 +96,6 @@ class Site @jekyll.config end - attr_reader :collections - def collections_names @jekyll.config['collections'].keys end @@ -136,8 +121,8 @@ class Site # idioma actual collection = default_lang if collection == 'posts' && i18n? - _collection = @collections[collection] - return _collection if _collection + c = @collections[collection] + return c if c Rails.logger.info "Procesando #{collection}" @@ -234,7 +219,7 @@ class Site defail! # TODO: ya van tres métodos donde usamos esta idea, convertir en un # helper o algo - r = File.open(queue_file, File::RDWR | File::CREAT, 0o640) do |f| + File.open(queue_file, File::RDWR | File::CREAT, 0o640) do |f| # Bloquear el archivo para que no sea accedido por otro # proceso u otra editora f.flock(File::LOCK_EX) @@ -267,7 +252,7 @@ class Site # # new_order es un hash cuya key es la posición actual del post y el # valor la posición nueva - def reorder_collection(collection = 'posts', new_order) + def reorder_collection(collection, new_order) # Tenemos que pasar el mismo orden return if new_order.values.map(&:to_i).sort != new_order.keys.map(&:to_i).sort @@ -354,40 +339,4 @@ class Site Jekyll::Site.new(config) end - - def self.cached?(site) - @sites_cache[site.to_sym].present? - end - - # Carga un sitio y lo cachea - def self.find_by_dir(dir) - @sites_cache ||= {} - site = File.basename(dir).to_sym - @sites_cache[site] ||= Dir.chdir(dir) do - jekyll = Site.load_jekyll(Dir.pwd) - Site.new(jekyll: jekyll, path: dir) - end - end - - # Encuentra un sitio - def self.find(site) - dir = Site.site_path_for(site) - return nil unless Site.jekyll? dir - - Site.find_by_dir(dir) - end - - # Devuelve todos los directorios de los sitios - def self.all_dirs - Pathname.new(Site.site_path).children.map(&:expand_path).map(&:to_s) - end - - # Obtiene todos los sitios - def self.all - Site.all_dirs.map do |j| - next unless Site.jekyll? j - - Site.find_by_dir(j) - end.compact - end end diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index fc827e6b..5fee2951 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -1,6 +1,5 @@ # frozen_string_literal: true -# # Usuarie de la plataforma class Usuarie < ApplicationRecord devise :database_authenticatable, @@ -8,4 +7,8 @@ class Usuarie < ApplicationRecord :confirmable, :lockable, :registerable validates_uniqueness_of :email + + has_and_belongs_to_many :sites + has_and_belongs_to_many :sites_as_invitade, class_name: 'Site', + join_table: 'invitades_sites' end diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index cd74149c..25d6de28 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -3,9 +3,17 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.plural 'invitadx', 'invitadxs' inflect.singular 'invitadxs', 'invitadx' + inflect.plural 'invitade', 'invitades' + inflect.singular 'invitades', 'invitade' + inflect.plural 'usuarie', 'usuaries' + inflect.singular 'usuaries', 'usuarie' end ActiveSupport::Inflector.inflections(:es) do |inflect| inflect.plural 'invitadx', 'invitadxs' inflect.singular 'invitadxs', 'invitadx' + inflect.plural 'invitade', 'invitades' + inflect.singular 'invitades', 'invitade' + inflect.plural 'usuarie', 'usuaries' + inflect.singular 'usuaries', 'usuarie' end diff --git a/db/migrate/20190703200455_create_sitios.rb b/db/migrate/20190703200455_create_sitios.rb new file mode 100644 index 00000000..5d2a3ca8 --- /dev/null +++ b/db/migrate/20190703200455_create_sitios.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +# Crea la tabla de sitios y las relaciones con Usuaries e Invitades +class CreateSitios < ActiveRecord::Migration[5.2] + def up + # Tabla de Sitios + create_table :sites do |t| + t.timestamps + t.string :name, index: true, unique: true + end + + # Relación HABTM entre Sitios y Usuaries + create_table :sites_usuaries, id: false do |t| + t.belongs_to :site, index: true + t.belongs_to :usuarie, index: true + end + + # Relación HABTM entre Sitios e Invitades + create_table :invitades_sites, id: false do |t| + t.belongs_to :site, index: true + t.belongs_to :usuarie, index: true + end + + ## Crear las relaciones correspondientes + # + # Obtener todos los sitios (estamos moviendo funcionalidad previa de + # Site + sites = Pathname.new(Site.site_path) + .children.map(&:expand_path).map(&:to_s) + + sites.each do |dir| + site = Site.create name: File.basename(dir) + + file = File.join([dir, '.usuarias']) + usuarias = File.exist?(file) ? File.read(file).split("\n").uniq : [] + + file = File.join([dir, '.invitadxs']) + invitadxs = File.exist?(file) ? File.read(file).split("\n").uniq : [] + + # Tenemos que crear a les usuaries porque no existían en ningún + # lado + usuarias.each do |email| + usuarie = Usuarie.find_by(email: email) + usuarie ||= Usuarie.create(email: email, + password: SecureRandom.hex) + site.usuaries << usuarie + end + + # Les Invitades ya están migrades + invitadxs.each do |email| + site.invitades << Usuarie.find_by(email: email) + end + end + end + + def down + drop_table :sites + drop_table :sites_usuaries + drop_table :invitades_sites + end +end diff --git a/db/schema.rb b/db/schema.rb index 02f60bf7..c7dd8373 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -10,7 +12,28 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_190_703_190_859) do +ActiveRecord::Schema.define(version: 20_190_703_200_455) do + create_table 'invitades_sites', id: false, force: :cascade do |t| + t.integer 'site_id' + t.integer 'usuarie_id' + t.index ['site_id'], name: 'index_invitades_sites_on_site_id' + t.index ['usuarie_id'], name: 'index_invitades_sites_on_usuarie_id' + end + + create_table 'sites', force: :cascade do |t| + t.datetime 'created_at', null: false + t.datetime 'updated_at', null: false + t.string 'name' + t.index ['name'], name: 'index_sites_on_name' + end + + create_table 'sites_usuaries', id: false, force: :cascade do |t| + t.integer 'site_id' + t.integer 'usuarie_id' + t.index ['site_id'], name: 'index_sites_usuaries_on_site_id' + t.index ['usuarie_id'], name: 'index_sites_usuaries_on_usuarie_id' + end + create_table 'usuaries', force: :cascade do |t| t.datetime 'created_at', null: false t.datetime 'updated_at', null: false diff --git a/doc/autenticacion.md b/doc/autenticacion.md index b83ed840..b73ff024 100644 --- a/doc/autenticacion.md +++ b/doc/autenticacion.md @@ -21,3 +21,19 @@ cosas más. Planeamos que Sutty también sea un proveedor de oAuth, para poder integrarla con otras plataformas comunitarias (rocket.chat/mattermost.com principalmente). + +## Base de datos + +Los Sitios tienen una contraparte física, de archivos, pero también se +crean en la base de datos para establecer relaciones con Usuaries. + +Une Usuarie puede tener muchos Sitios y viceversa. En Rails esto se +llama "tiene y pertenece a muchos" (HABTM en inglés). + +Sin embargo también queremos saber qué rol tienen, con lo que +necesitamos dos tablas de HABTM, una de Invitades y otra de Usuaries. +De lo contrario necesitamos establecer roles y ya entramos en las +dificultades que decíamos más arriba. + +No podemos saber desde cuándo se creo la relación, a menos que tengamos +una tabla de actividades.