aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/resource.rb1
-rw-r--r--app/models/section.rb1
-rw-r--r--db/migrate/20201008184053_add_dewey_id_to_categories_and_sections.rb8
-rw-r--r--db/migrate/20201008190558_create_join_table_resource_sections.rb8
-rw-r--r--db/schema.rb11
-rw-r--r--db/seeds.rb22
-rw-r--r--doc/import/README.md30
-rw-r--r--doc/import/categories-fr.json395
8 files changed, 475 insertions, 1 deletions
diff --git a/app/models/resource.rb b/app/models/resource.rb
index e67d164..cd43bf9 100644
--- a/app/models/resource.rb
+++ b/app/models/resource.rb
@@ -3,6 +3,7 @@ class Resource < ApplicationRecord
include UUIDParameter
belongs_to :agent
+ has_and_belongs_to_many :sections
# Figure out the requested property name
def method_missing(name, *args, &block)
diff --git a/app/models/section.rb b/app/models/section.rb
index 0a1fbf2..6cfeb38 100644
--- a/app/models/section.rb
+++ b/app/models/section.rb
@@ -1,6 +1,7 @@
class Section < ApplicationRecord
belongs_to :category
has_one :taxonomy, through: :category
+ has_and_belongs_to_many :resources
acts_as_list column: :rank, scope: :category
diff --git a/db/migrate/20201008184053_add_dewey_id_to_categories_and_sections.rb b/db/migrate/20201008184053_add_dewey_id_to_categories_and_sections.rb
new file mode 100644
index 0000000..d876b47
--- /dev/null
+++ b/db/migrate/20201008184053_add_dewey_id_to_categories_and_sections.rb
@@ -0,0 +1,8 @@
+class AddDeweyIdToCategoriesAndSections < ActiveRecord::Migration[6.0]
+ def change
+ add_column :categories, :dewey_id, :integer
+ add_column :sections, :dewey_id, :integer
+ add_index :categories, :dewey_id, unique: true
+ add_index :sections, :dewey_id, unique: true
+ end
+end
diff --git a/db/migrate/20201008190558_create_join_table_resource_sections.rb b/db/migrate/20201008190558_create_join_table_resource_sections.rb
new file mode 100644
index 0000000..d01c27f
--- /dev/null
+++ b/db/migrate/20201008190558_create_join_table_resource_sections.rb
@@ -0,0 +1,8 @@
+class CreateJoinTableResourceSections < ActiveRecord::Migration[6.0]
+ def change
+ create_join_table :resources, :sections do |t|
+ # t.index [:resource_id, :section_id]
+ # t.index [:section_id, :resource_id]
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 5a8bba7..16ba65c 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.define(version: 2020_10_08_133300) do
+ActiveRecord::Schema.define(version: 2020_10_08_190558) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -45,6 +45,8 @@ ActiveRecord::Schema.define(version: 2020_10_08_133300) do
t.integer "sections_count", default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
+ t.integer "dewey_id"
+ t.index ["dewey_id"], name: "index_categories_on_dewey_id", unique: true
t.index ["taxonomy_id"], name: "index_categories_on_taxonomy_id"
end
@@ -58,6 +60,11 @@ ActiveRecord::Schema.define(version: 2020_10_08_133300) do
t.index ["uuid"], name: "index_resources_on_uuid", unique: true
end
+ create_table "resources_sections", id: false, force: :cascade do |t|
+ t.bigint "resource_id", null: false
+ t.bigint "section_id", null: false
+ end
+
create_table "sections", force: :cascade do |t|
t.string "name", limit: 64
t.string "summary", limit: 136
@@ -67,7 +74,9 @@ ActiveRecord::Schema.define(version: 2020_10_08_133300) do
t.integer "rank", default: 0
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
+ t.integer "dewey_id"
t.index ["category_id"], name: "index_sections_on_category_id"
+ t.index ["dewey_id"], name: "index_sections_on_dewey_id", unique: true
end
create_table "taxonomies", force: :cascade do |t|
diff --git a/db/seeds.rb b/db/seeds.rb
index 8a4c670..ea9fc25 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -26,3 +26,25 @@ Taxonomy.find_or_create_by(
uuid: '2519915f-d19c-4281-b758-f5ddb889d7fa',
agent_id: dewey.id
)
+
+# Create French categories and sections
+if Category.count == 0
+ dewey_taxo = Taxonomy.first
+ cats = JSON.parse(IO.read('doc/import/categories-fr.json'))
+ cats.each do |cat|
+ c = Category.create(name: cat['name'], dewey_id: cat['id'], taxonomy_id: dewey_taxo.id, color: cat['color'])
+ cat['sections'].each do |sec|
+ Section.create(name: sec['name'], category_id: c.id, dewey_id: sec['id'], color: sec['color'])
+ end
+ end
+ # Now that we have all we need, update resources_sections...
+ Resource.all.each do |res|
+ sec_ids = res.feature['properties']['categories']
+ next if sec_ids.empty?
+ sec_ids.each do |id|
+ s = Section.find_by(dewey_id: id)
+ res.sections << s if s.present?
+ res.save
+ end
+ end
+end
diff --git a/doc/import/README.md b/doc/import/README.md
index b65225e..f5c4096 100644
--- a/doc/import/README.md
+++ b/doc/import/README.md
@@ -30,3 +30,33 @@ locs['features'].each do |f|
Resource.create(agent_id: agent.id, feature: f)
end
```
+### Importing categories
+
+We have a JSON file in French for categories in `doc/import/categories-fr.json`.
+
+From the console:
+
+```ruby
+if Category.count == 0
+ dewey_taxo = Taxonomy.first
+ cats = JSON.parse(IO.read('doc/import/categories-fr.json'))
+ cats.each do |cat|
+ c = Category.create(name: cat['name'], dewey_id: cat['id'], taxonomy_id: dewey_taxo.id, color: cat['color'])
+ cat['sections'].each do |sec|
+ Section.create(name: sec['name'], category_id: c.id, dewey_id: sec['id'], color: sec['color'])
+ end
+ end
+ # Now that we have all we need, update resources_sections...
+ Resource.all.each do |res|
+ sec_ids = res.feature['properties']['categories']
+ next if sec_ids.empty?
+ sec_ids.each do |id|
+ s = Section.find_by(dewey_id: id)
+ res.sections << s if s.present?
+ res.save
+ end
+ end
+end
+```
+
+It's taken into account in `rails db:seed`
diff --git a/doc/import/categories-fr.json b/doc/import/categories-fr.json
new file mode 100644
index 0000000..ec22790
--- /dev/null
+++ b/doc/import/categories-fr.json
@@ -0,0 +1,395 @@
+[
+ {
+ "id": 8,
+ "name": "Se loger",
+ "sections": [
+ {
+ "id": 148,
+ "name": "Campings"
+ },
+ {
+ "id": 158,
+ "name": "Maisons de soin"
+ },
+ {
+ "id": 130,
+ "name": "Community land trust"
+ },
+ {
+ "id": 198,
+ "name": "Community living (for the homeless)"
+ },
+ {
+ "id": 150,
+ "name": "Homeless shelters (by night)"
+ },
+ {
+ "id": 149,
+ "name": "Auberges de jeunesse"
+ },
+ {
+ "id": 165,
+ "name": "Coopérative d'habitants"
+ },
+ {
+ "id": 131,
+ "name": "Occupations légalisées"
+ },
+ {
+ "id": 168,
+ "name": "Participatory housing, cohousing"
+ },
+ {
+ "id": 164,
+ "name": "Coopératives de locataires"
+ },
+ {
+ "id": 114,
+ "name": "Droit au logement"
+ }
+ ],
+ "color": "#BCBCBC"
+ },
+ {
+ "id": 6,
+ "name": "1. S'alimenter",
+ "sections": [
+ {
+ "name": "Marchés",
+ "id": 170
+ },
+ {
+ "name": "Ateliers cuisine",
+ "id": 180
+ },
+ {
+ "name": "Spots 'plantes aromatiques'",
+ "id": 155
+ },
+ {
+ "name": "Épiceries solidaires",
+ "id": 135
+ },
+ {
+ "name": "Eau potable",
+ "id": 115
+ },
+ {
+ "name": "Repas gratuits",
+ "id": 154
+ },
+ {
+ "name": "Restaurants sociaux",
+ "id": 118
+ },
+ {
+ "name": "Initiatives de récup' alimentaire",
+ "id": 28
+ },
+ {
+ "name": "GASAP (groupes d'achat)",
+ "id": 27
+ },
+ {
+ "name": "GASAP (producteurs)",
+ "id": 185
+ }
+ ],
+ "color": "#FF9200"
+ },
+ {
+ "id": 11,
+ "name": "2. Se laver, s'habiller",
+ "sections": [
+ {
+ "name": "Boîtes à dons",
+ "id": 210
+ },
+ {
+ "name": "Vestiaires sociaux",
+ "id": 156
+ },
+ {
+ "name": "Donneries, marchés gratuits",
+ "id": 46
+ },
+ {
+ "name": "Douches publiques",
+ "id": 144
+ },
+ {
+ "name": "Friperies, vêtements de 2ème main",
+ "id": 104
+ }
+ ],
+ "color": "#FFEB00"
+ },
+ {
+ "id": 10,
+ "name": "3. Guérir, se soigner",
+ "sections": [
+ {
+ "name": "Maisons médicales",
+ "id": 18
+ },
+ {
+ "name": "Réseaux de santé",
+ "id": 145
+ },
+ {
+ "name": "Services de santé pour personnes précaires",
+ "id": 157
+ }
+ ],
+ "color": "#7CFB80"
+ },
+ {
+ "id": 15,
+ "name": "4. Recycler, réparer",
+ "sections": [
+ {
+ "name": "Magasins de seconde main",
+ "id": 699
+ },
+ {
+ "name": "Ateliers de travail du bois",
+ "id": 138
+ },
+ {
+ "name": "Récup' de cartouches d'imprimantes",
+ "id": 136
+ },
+ {
+ "name": "Boîtes à livres",
+ "id": 50
+ },
+ {
+ "name": "Aide au compostage",
+ "id": 132
+ },
+ {
+ "name": "Repair cafés",
+ "id": 42
+ },
+ {
+ "name": "Récup' de matériaux de construction",
+ "id": 113
+ },
+ {
+ "name": "Bulles à vêtements",
+ "id": 206
+ },
+ {
+ "name": "Matériaux informatiques recyclés",
+ "id": 47
+ },
+ {
+ "name": "Recyclage de verre",
+ "id": 205
+ },
+ {
+ "name": "Marchés aux puces",
+ "id": 120
+ }
+ ],
+ "color": "#02ACCC"
+ },
+ {
+ "id": 7,
+ "name": "5. respirer, se mettre au vert",
+ "sections": [
+ {
+ "name": "Soutien aux potagistes",
+ "id": 128
+ },
+ {
+ "name": "Composts collectifs ou 'de quartier'",
+ "id": 121
+ },
+ {
+ "name": "Potagers & vergers",
+ "id": 116
+ },
+ {
+ "name": "Réserves naturelles",
+ "id": 133
+ },
+ {
+ "name": "Associations de naturalistes",
+ "id": 194
+ },
+ {
+ "name": "Parcs publics",
+ "id": 129
+ },
+ {
+ "name": "Grainothèques, bourses aux semences",
+ "id": 125
+ },
+ {
+ "name": "Associations apicoles",
+ "id": 127
+ }
+ ],
+ "color": "#97C000"
+ },
+ {
+ "id": 3,
+ "name": "6. Se rencontrer, s'entraider",
+ "sections": [
+ {
+ "name": "Comités de quartiers",
+ "id": 102
+ },
+ {
+ "name": "Associations de soutien aux seniors",
+ "id": 19
+ },
+ {
+ "name": "Maisons de Jeunes",
+ "id": 17
+ },
+ {
+ "name": "Soutien à l'enfance et à la famille",
+ "id": 14
+ },
+ {
+ "name": "Maisons de quartiers",
+ "id": 10
+ },
+ {
+ "name": "Monnaies complémentaires",
+ "id": 211
+ },
+ {
+ "name": "Associations de soutien scolaire",
+ "id": 119
+ },
+ {
+ "name": "Associations de Femmes",
+ "id": 15
+ },
+ {
+ "name": "Accueil des réfugiés",
+ "id": 188
+ },
+ {
+ "name": "Soutien aux personnes en situation d'handicap",
+ "id": 16
+ },
+ {
+ "name": "Accueil des primo-arrivants",
+ "id": 197
+ },
+ {
+ "name": "Coopération et solidarité internationale",
+ "id": 209
+ },
+ {
+ "name": "Associations pour l'égalité des genres",
+ "id": 202
+ },
+ {
+ "name": "Centres communautaires NL",
+ "id": 204
+ },
+ {
+ "name": "Initiatives de récup' alimentaire",
+ "id": 201
+ },
+ {
+ "name": "Soutien aux personnes précaires",
+ "id": 193
+ },
+ {
+ "name": "Systèmes d'échange locaux (SEL)",
+ "id": 184
+ }
+ ],
+ "color": "#C6B117"
+ },
+ {
+ "id": 2,
+ "name": "7. Apprendre, se former",
+ "sections": [
+ {
+ "name": "Association d'écologie urbaine",
+ "id": 90
+ },
+ {
+ "name": "Espaces de travail partagés, co-working",
+ "id": 87
+ },
+ {
+ "name": "Soutien à l'économie locale",
+ "id": 12
+ },
+ {
+ "name": "Associations d'éducation permanente",
+ "id": 13
+ }
+ ],
+ "color": "#7E8AE0"
+ },
+ {
+ "id": 13,
+ "name": "8. S'exprimer, communiquer",
+ "sections": [
+ {
+ "name": "Bornes d'accès à Internet",
+ "id": 124
+ },
+ {
+ "name": "Hackerspaces",
+ "id": 43
+ },
+ {
+ "name": "Médias indépendants",
+ "id": 109
+ },
+ {
+ "name": "Écrivains publics",
+ "id": 177
+ },
+ {
+ "name": "Lieux de promotion du logiciel libre",
+ "id": 174
+ }
+ ],
+ "color": "#677362"
+ },
+ {
+ "id": 9,
+ "name": "9. Bouger, se déplacer",
+ "sections": [
+ {
+ "name": "Cours de vélo",
+ "id": 179
+ },
+ {
+ "name": "Ateliers vélo",
+ "id": 71
+ },
+ {
+ "name": "Vélos partagés",
+ "id": 147
+ },
+ {
+ "name": "Livraisons à vélo",
+ "id": 140
+ },
+ {
+ "name": "Pompes à vélos",
+ "id": 212
+ },
+ {
+ "name": "Taxis collectifs (Collecto)",
+ "id": 196
+ },
+ {
+ "name": "Voitures partagées",
+ "id": 141
+ }
+ ]
+ }
+]