summaryrefslogtreecommitdiff
path: root/db
diff options
context:
space:
mode:
Diffstat (limited to 'db')
-rw-r--r--db/data/dolibarr_plant_requirements.csv9
-rw-r--r--db/data/nutrient_profiles.csv (renamed from db/data/nutrient_requirements.csv)0
-rw-r--r--db/migrate/20250901112954_rename_crops_to_nutrient_profiles.rb10
-rw-r--r--db/schema.rb53
-rw-r--r--db/seeds.rb13
-rw-r--r--db/seeds/1_nutrients.rb24
-rw-r--r--db/seeds/3_crops.rb125
-rw-r--r--db/seeds/4_beds_and_rafts.rb24
-rw-r--r--db/seeds/5_fertilizer_components.rb.bkp38
-rw-r--r--db/seeds/6_fertilizer_products.rb143
-rw-r--r--db/seeds/NutrientMeasurement.rb (renamed from db/seeds/2_nutrient_measurements.rb)2
-rw-r--r--db/seeds/NutrientProfile.rb109
12 files changed, 165 insertions, 385 deletions
diff --git a/db/data/dolibarr_plant_requirements.csv b/db/data/dolibarr_plant_requirements.csv
new file mode 100644
index 0000000..333ea38
--- /dev/null
+++ b/db/data/dolibarr_plant_requirements.csv
@@ -0,0 +1,9 @@
+Cycles et productions,NNO3,P,K,Ca,Mg,S,Fe,Zn,B,Mn,Cu,Mo
+Formule moyenne générale,160.00,30.00,230.00,100.00,30.00,60.00,5.00,0.15,0.30,0.50,0.15,0.05
+Salades,130.00,60.00,300.00,100.00,30.00,60.00,2.00,0.10,0.50,0.50,0.05,0.05
+Développement floral,190.00,50.00,210.00,200.00,50.00,66.00,5.00,0.15,0.30,0.50,0.15,0.05
+Tomates général,140.00,50.00,352.00,180.00,50.00,168.00,5.00,0.10,0.30,0.80,0.07,0.03
+Jeunes tomates,100.00,40.00,200.00,100.00,20.00,53.00,3.00,0.10,0.30,0.80,0.07,0.03
+Tomate premiers fruits,130.00,55.00,300.00,150.00,33.00,109.00,3.00,0.10,0.30,0.80,0.07,0.03
+Tomate mûre,180.00,65.00,400.00,400.00,45.00,144.00,3.00,0.10,0.30,0.80,0.07,0.03
+Framboise - tous stades,70.00,12.00,88.00,90.00,24.00,48.00,0.56,0.33,0.11,0.11,0.03,0.01
diff --git a/db/data/nutrient_requirements.csv b/db/data/nutrient_profiles.csv
index 61406b8..61406b8 100644
--- a/db/data/nutrient_requirements.csv
+++ b/db/data/nutrient_profiles.csv
diff --git a/db/migrate/20250901112954_rename_crops_to_nutrient_profiles.rb b/db/migrate/20250901112954_rename_crops_to_nutrient_profiles.rb
new file mode 100644
index 0000000..5b46df1
--- /dev/null
+++ b/db/migrate/20250901112954_rename_crops_to_nutrient_profiles.rb
@@ -0,0 +1,10 @@
+class RenameCropsToNutrientProfiles < ActiveRecord::Migration[8.0]
+ def change
+ rename_table :crops, :nutrient_profiles
+
+ rename_column :rafts, :crop_id, :crop_nutrient_need_id
+ add_index :rafts, :crop_nutrient_need_id unless index_exists?(:rafts, :crop_nutrient_need_id)
+
+ remove_column :nutrient_profiles, :crop_type
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index b5f2e03..feb2fd0 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[8.0].define(version: 2025_08_24_163257) do
+ActiveRecord::Schema[8.0].define(version: 2025_09_01_112954) do
create_table "beds", force: :cascade do |t|
t.integer "location", null: false
t.datetime "created_at", null: false
@@ -18,29 +18,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_24_163257) do
t.index ["location"], name: "index_beds_on_location", unique: true
end
- create_table "crops", force: :cascade do |t|
- t.string "name"
- t.integer "crop_type", default: 1, null: false
- t.float "nno3"
- t.float "p"
- t.float "k"
- t.float "ca"
- t.float "mg"
- t.float "s"
- t.float "na"
- t.float "cl"
- t.float "si"
- t.float "fe"
- t.float "zn"
- t.float "b"
- t.float "mn"
- t.float "cu"
- t.float "mo"
- t.float "nnh4"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
create_table "fertilizer_components", force: :cascade do |t|
t.string "name"
t.string "formula"
@@ -105,6 +82,28 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_24_163257) do
t.index ["measured_on"], name: "index_nutrient_measurements_on_measured_on", unique: true
end
+ create_table "nutrient_profiles", force: :cascade do |t|
+ t.string "name"
+ t.float "nno3"
+ t.float "p"
+ t.float "k"
+ t.float "ca"
+ t.float "mg"
+ t.float "s"
+ t.float "na"
+ t.float "cl"
+ t.float "si"
+ t.float "fe"
+ t.float "zn"
+ t.float "b"
+ t.float "mn"
+ t.float "cu"
+ t.float "mo"
+ t.float "nnh4"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "nutrients", force: :cascade do |t|
t.string "formula"
t.string "name"
@@ -115,16 +114,16 @@ ActiveRecord::Schema[8.0].define(version: 2025_08_24_163257) do
create_table "rafts", force: :cascade do |t|
t.integer "bed_id", null: false
t.integer "location", null: false
- t.integer "crop_id"
+ t.integer "crop_nutrient_need_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["bed_id", "location"], name: "index_rafts_on_bed_id_and_location", unique: true
t.index ["bed_id"], name: "index_rafts_on_bed_id"
- t.index ["crop_id"], name: "index_rafts_on_crop_id"
+ t.index ["crop_nutrient_need_id"], name: "index_rafts_on_crop_nutrient_need_id"
end
add_foreign_key "fertilizer_compositions", "fertilizer_components"
add_foreign_key "fertilizer_compositions", "fertilizer_products"
add_foreign_key "rafts", "beds"
- add_foreign_key "rafts", "crops"
+ add_foreign_key "rafts", "nutrient_profiles", column: "crop_nutrient_need_id"
end
diff --git a/db/seeds.rb b/db/seeds.rb
index 848db0d..245247e 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -8,6 +8,15 @@
# MovieGenre.find_or_create_by!(name: genre_name)
# end
-Dir[Rails.root.join("db/seeds/*.rb")].sort.each do |seed|
- load seed
+MODELS = [ NutrientMeasurement,
+ NutrientProfile
+ ].freeze
+
+def seed_file_for(model_class)
+ Rails.root.join("db", "seeds", "#{model_class.name}.rb")
+end
+
+MODELS.each do |model|
+ load seed_file_for(model)
+ printf "%-22s %3s\n", model.name, model.count
end
diff --git a/db/seeds/1_nutrients.rb b/db/seeds/1_nutrients.rb
deleted file mode 100644
index dab2249..0000000
--- a/db/seeds/1_nutrients.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-NUTRIENTS = [
- [ "nno3", "nitrate" ],
- [ "p", "phosphore" ],
- [ "k", "potassium" ],
- [ "ca", "calcium" ],
- [ "mg", "magnésium" ],
- [ "s", "soufre" ],
- [ "na", "sodium" ],
- [ "cl", "chlore" ],
- [ "si", "silice" ],
- [ "fe", "fer" ],
- [ "zn", "zinc" ],
- [ "b", "bore" ],
- [ "mn", "manganèse" ],
- [ "cu", "cuivre" ],
- [ "mo", "molybdène" ],
- [ "nnh4", "ammonium" ]
-]
-
-NUTRIENTS.each do |formula, name|
- Nutrient.find_or_create_by!(formula:) { |n| n.name = name }
-end
-
-puts "Nutrients: #{Nutrient.count}"
diff --git a/db/seeds/3_crops.rb b/db/seeds/3_crops.rb
deleted file mode 100644
index 6a5c10f..0000000
--- a/db/seeds/3_crops.rb
+++ /dev/null
@@ -1,125 +0,0 @@
-# crop_type: 0=leafy greens, 1=fruits, 2=herbs
-
-LEAFY = {
- nno3: 150,
- p: 31,
- k: 210,
- ca: 90,
- mg: 24,
- s: 32,
- fe: 1.0,
- mn: 0.25,
- zn: 0.13,
- b: 0.16,
- cu: 0.023,
- mo: 0.024,
- nnh4: 5,
- # keep low for leafy
- na: 10,
- cl: 5,
- si: 20
-}
-
-HERB = LEAFY # Herbs run well on the Cornell leafy recipe
-
-TOMATO = {
- # CEAC Stage 3 "multi-crop" / mature tomato
- nno3: 190,
- p: 47,
- k: 350,
- ca: 200,
- mg: 65,
- s: 102,
- fe: 2.0,
- mn: 0.55,
- zn: 0.33,
- b: 0.28,
- cu: 0.05,
- mo: 0.05,
- nnh4: 0,
- # CEAC recipes are NO3-N; keep NH4 minimal
- na: 20,
- cl: 25,
- si: 20
-}
-
-HOT_PEPPER = {
- # Mature greenhouse pepper (HortAmericas summary of UA recipes)
- nno3: 180,
- p: 50,
- k: 280,
- ca: 200,
- mg: 45,
- s: 20,
- fe: 1.0,
- mn: 0.55,
- zn: 0.33,
- b: 0.30,
- cu: 0.05,
- mo: 0.05,
- nnh4: 15,
- na: 20,
- cl: 10,
- si: 20
-}
-
-STRAWBERRY = {
- # UA strawberry (Yamazaki) emphasizes lower EC; use conservative macros
- nno3: 120,
- p: 30,
- k: 200,
- ca: 120,
- mg: 35,
- s: 50,
- fe: 1.5,
- mn: 0.50,
- zn: 0.20,
- b: 0.30,
- cu: 0.05,
- mo: 0.05,
- nnh4: 5,
- na: 10,
- cl: 5,
- si: 20
-}
-
-RASPBERRY = {
- # Sparse data; align with strawberry but a touch higher vigor
- nno3: 140,
- p: 35,
- k: 230,
- ca: 150,
- mg: 40,
- s: 50,
- fe: 1.5,
- mn: 0.50,
- zn: 0.20,
- b: 0.30,
- cu: 0.05,
- mo: 0.05,
- nnh4: 5,
- na: 15,
- cl: 5,
- si: 20
-}
-
-[
- [ "lettuce", 0, LEAFY ],
- [ "kale", 0, LEAFY ],
- [ "cabbage, chinese", 0, LEAFY ],
- [ "tomatoes", 1, TOMATO ],
- [ "raspberries", 1, RASPBERRY ],
- [ "strawberries", 1, STRAWBERRY ],
- [ "hot peppers", 1, HOT_PEPPER ],
- [ "parsley", 2, HERB ],
- [ "chives", 2, HERB ],
- [ "italian basil", 2, HERB ],
- [ "dill", 2, HERB ]
-].each do |name, type, nutrient_requirements|
- Crop.find_or_create_by!(name: name) do |c|
- c.crop_type = type
- c.attributes = nutrient_requirements
- end
-end
-
-puts "Crops: #{Crop.count}"
diff --git a/db/seeds/4_beds_and_rafts.rb b/db/seeds/4_beds_and_rafts.rb
deleted file mode 100644
index 1cd95dc..0000000
--- a/db/seeds/4_beds_and_rafts.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-BEDS = 14
-RAFTS = 10
-
-1.upto(BEDS) do |b|
- bed = Bed.find_or_create_by!(location: b)
-
- crop_name = case b
- when 1..2 then "tomatoes"
- when 3 then "hot peppers"
- when 4 then "chives"
- when 5 then "italian basil"
- when 6..7 then "cabbage, chinese"
- else "lettuce"
- end
-
- 1.upto(RAFTS) do |r|
- raft = bed.rafts.find_or_create_by!(location: r) do |raft|
- raft.crop = Crop.find_by!(name: crop_name)
- end
- end
-end
-
-puts "Beds: #{Bed.count}"
-puts "Rafts: #{Raft.count}"
diff --git a/db/seeds/5_fertilizer_components.rb.bkp b/db/seeds/5_fertilizer_components.rb.bkp
deleted file mode 100644
index 8a1fc54..0000000
--- a/db/seeds/5_fertilizer_components.rb.bkp
+++ /dev/null
@@ -1,38 +0,0 @@
-FERTILIZER_COMPONENTS = [
- # Macros / bases
- { name: "Potassium Nitrate", formula: "KNO3", nno3: 13.50, k: 38.60 },
- { name: "Calcium Nitrate", formula: "Ca(NO3)2·xH2O", nno3: 15.50, ca: 18.94 },
- { name: "Ammonium Nitrate", formula: "NH4NO3", nno3: 13.50, nnh4: 13.50 }, # total N ≈ 27
- { name: "Diammonium Phosphate", formula: "(NH4)2HPO4", p: 21.00 }, # NH4 can be added later if desired
-
- # Acids / buffers
- { name: "Nitric Acid 53%", formula: "HNO3", nno3: 11.70 },
- { name: "Potassium Bicarbonate", formula: "KHCO3", k: 39.05 },
- { name: "Calcium Carbonate", formula: "CaCO3", ca: 38.00 },
-
- # K–Mg–S complex (Patentkali-type blend)
- { name: "Potassium Sulfate blend (K–Mg–S + NaCl)", formula: "K2SO4+MgSO4+NaCl",
- p: 0.44, k: 22.66, mg: 6.16, s: 17.77, na: 2.16, cl: 3.34 },
-
- # Sulfates (micros / secondary)
- { name: "Magnesium Sulfate", formula: "MgSO4·7H2O", mg: 9.648, s: 13.016 },
- { name: "Manganese Sulfate", formula: "MnSO4", s: 7.17, mn: 12.00 },
- { name: "Zinc Sulfate (Fiza Zinc)", formula: "ZnSO4", zn: 12.00 },
-
- # Chelates / traces
- { name: "Iron DTPA 11.8%", formula: "Fe-DTPA", fe: 11.80 },
- { name: "HelioCopper (Cu chelate)", formula: "Cu-chelate", cu: 40.00 },
-
- # Boron & Mo sources
- { name: "Boron–Molybdenum (Boronia LS)", formula: "B+Mo", b: 13.50, mo: 0.028 },
- { name: "Boronia MO12 (10L)", formula: "B+Mn+Cu", b: 8.90, mn: 0.089, cu: 0.89 },
- { name: "Sodium Molybdate", formula: "Na2MoO4", mo: 39.50 }
-]
-
-FERTILIZER_COMPONENTS.each do |attrs|
- FertilizerComponent.find_or_create_by!(name: attrs[:name]) do |c|
- c.attributes = attrs
- end
-end
-
-puts "Fertilizer components: #{FertilizerComponent.count}"
diff --git a/db/seeds/6_fertilizer_products.rb b/db/seeds/6_fertilizer_products.rb
deleted file mode 100644
index 6769bde..0000000
--- a/db/seeds/6_fertilizer_products.rb
+++ /dev/null
@@ -1,143 +0,0 @@
-FERTILIZER_RECIPES = [
- {
- name: "Multi K Reci",
- purity: 99.0,
- composition: [
- { component: {
- name: "Potassium nitrate",
- formula: "KNO3",
- nno3: 13.0,
- k: 46.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Fixa Mn",
- purity: 98.0,
- composition: [
- { component: {
- name: "Manganese sulfate",
- formula: "MnSO4·H2O",
- mn: 32.0,
- s: 18.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Multi-Cal Haïfa",
- purity: 99.0,
- composition: [
- { component: {
- name: "Calcium nitrate",
- formula: "Ca(NO3)2·4H2O",
- nno3: 15.5,
- ca: 19.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "DAP 18/46/00",
- purity: 100.0,
- composition: [
- { component: {
- name: "Diammonium phosphate",
- formula: "(NH4)2HPO4",
- nnh4: 18.0,
- p: 20.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Patenkali",
- purity: 100.0,
- composition: [
- { component: {
- name: "Potassium sulfate",
- formula: "K2SO4",
- k: 50.0,
- s: 18.0
- }, percent_w: 100.0 }
- ]
- },
- {
- name: "Eso Top",
- purity: 100.0,
- composition: [
- { component: {
- name: "Magnesium sulfate",
- formula: "MgSO4·7H2O",
- mg: 9.8,
- s: 13.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Ammonitrate 27",
- purity: 100.0,
- composition: [
- { component: {
- name: "Ammonium nitrate",
- formula: "NH4NO3",
- nno3: 13.5,
- nnh4: 13.5 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Fer chélaté",
- purity: 100.0,
- composition: [
- { component: {
- name: "Iron chelate (EDDHA)",
- formula: "Fe-EDDHA",
- fe: 6.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Carbonate de calcium",
- purity: 100.0,
- composition: [
- { component: {
- name: "Calcium carbonate",
- formula: "CaCO3",
- ca: 40.0 },
- percent_w: 100.0 }
- ]
- },
- {
- name: "Héliocuivre",
- purity: 100.0,
- composition: [
- { component: {
- name: "Copper chelate (EDTA)",
- formula: "Cu-EDTA",
- cu: 14.0 },
- percent_w: 100.0 }
- ]
- }
-]
-
-FERTILIZER_RECIPES.each do |recipe|
- product = FertilizerProduct.find_or_create_by!(name: recipe[:name]) do |fp|
- fp.purity = recipe[:purity]
- end
-
- recipe[:composition].each do |c|
- comp_attrs = c[:component]
- component = FertilizerComponent.find_or_create_by!(name: comp_attrs[:name]) do |fc|
- fc.formula = comp_attrs[:formula]
- end
- # update nutrient fields if missing
- component.update!(comp_attrs.except(:name, :formula))
-
- FertilizerComposition.find_or_create_by!(
- fertilizer_product: product,
- fertilizer_component: component
- ) do |fc|
- fc.percent_w = c[:percent_w]
- end
- end
-end
-
-puts "FertilizerProducts: #{FertilizerProduct.count}"
diff --git a/db/seeds/2_nutrient_measurements.rb b/db/seeds/NutrientMeasurement.rb
index 0ca14f1..fcf8cfa 100644
--- a/db/seeds/2_nutrient_measurements.rb
+++ b/db/seeds/NutrientMeasurement.rb
@@ -23,5 +23,3 @@ CSV.foreach(csv_path, headers: true) do |row|
m.nnh4 = row["nnh4"]
end
end
-
-puts "NutrientMeasurements: #{NutrientMeasurement.count}"
diff --git a/db/seeds/NutrientProfile.rb b/db/seeds/NutrientProfile.rb
new file mode 100644
index 0000000..04e16cc
--- /dev/null
+++ b/db/seeds/NutrientProfile.rb
@@ -0,0 +1,109 @@
+[ { name: "formule moyenne générale",
+ nno3: 160.00,
+ p: 30.00,
+ k: 230.00,
+ ca: 100.00,
+ mg: 30.00,
+ s: 60.00,
+ fe: 5.00,
+ zn: 0.15,
+ b: 0.30,
+ mn: 0.50,
+ cu: 0.15,
+ mo: 0.05 },
+ { name: "salades",
+ nno3: 130.00,
+ p: 60.00,
+ k: 300.00,
+ ca: 100.00,
+ mg: 30.00,
+ s: 60.00,
+ fe: 2.00,
+ zn: 0.10,
+ b: 0.50,
+ mn: 0.50,
+ cu: 0.05,
+ mo: 0.05 },
+ { name: "développement floral",
+ nno3: 190.00,
+ p: 50.00,
+ k: 210.00,
+ ca: 200.00,
+ mg: 50.00,
+ s: 66.00,
+ fe: 5.00,
+ zn: 0.15,
+ b: 0.30,
+ mn: 0.50,
+ cu: 0.15,
+ mo: 0.05 },
+ { name: "tomates général",
+ nno3: 140.00,
+ p: 50.00,
+ k: 352.00,
+ ca: 180.00,
+ mg: 50.00,
+ s: 168.00,
+ fe: 5.00,
+ zn: 0.10,
+ b: 0.30,
+ mn: 0.80,
+ cu: 0.07,
+ mo: 0.03 },
+ { name: "jeunes tomates",
+ nno3: 100.00,
+ p: 40.00,
+ k: 200.00,
+ ca: 100.00,
+ mg: 20.00,
+ s: 53.00,
+ fe: 3.00,
+ zn: 0.10,
+ b: 0.30,
+ mn: 0.80,
+ cu: 0.07,
+ mo: 0.03 },
+ { name: "tomate premiers fruits",
+ nno3: 130.00,
+ p: 55.00,
+ k: 300.00,
+ ca: 150.00,
+ mg: 33.00,
+ s: 109.00,
+ fe: 3.00,
+ zn: 0.10,
+ b: 0.30,
+ mn: 0.80,
+ cu: 0.07,
+ mo: 0.03 },
+ { name: "tomate mûre",
+ nno3: 180.00,
+ p: 65.00,
+ k: 400.00,
+ ca: 400.00,
+ mg: 45.00,
+ s: 144.00,
+ fe: 3.00,
+ zn: 0.10,
+ b: 0.30,
+ mn: 0.80,
+ cu: 0.07,
+ mo: 0.03 },
+ { name: "framboise - tous stades",
+ nno3: 70.00,
+ p: 12.00,
+ k: 88.00,
+ ca: 90.00,
+ mg: 24.00,
+ s: 48.00,
+ fe: 0.56,
+ zn: 0.33,
+ b: 0.11,
+ mn: 0.11,
+ cu: 0.03,
+ mo: 0.01 },
+].each do |profile|
+ NutrientProfile.find_or_create_by!(name: profile[:name]) do |p|
+ p.attributes = profile
+ end
+end
Copyright 2019--2025 Marius PETER