summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/bed.rb5
-rw-r--r--app/models/crop.rb4
-rw-r--r--app/models/fertilizer_component.rb3
-rw-r--r--app/models/fertilizer_composition.rb6
-rw-r--r--app/models/fertilizer_product.rb7
-rw-r--r--app/models/nutrient.rb7
-rw-r--r--app/models/nutrient_measurement.rb14
-rw-r--r--app/models/nutrient_profile.rb13
-rw-r--r--app/models/raft.rb5
-rw-r--r--app/models/target.rb42
-rw-r--r--app/models/target_allocation.rb7
11 files changed, 76 insertions, 37 deletions
diff --git a/app/models/bed.rb b/app/models/bed.rb
deleted file mode 100644
index d41afe6..0000000
--- a/app/models/bed.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class Bed < ApplicationRecord
- has_many :rafts, -> { order(:location) }, dependent: :destroy
- accepts_nested_attributes_for :rafts
- validates :location, presence: true, uniqueness: true
-end
diff --git a/app/models/crop.rb b/app/models/crop.rb
deleted file mode 100644
index b0f168d..0000000
--- a/app/models/crop.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-class Crop < ApplicationRecord
- has_many :rafts
- enum :crop_type, { leafy: 0, fruit: 1, herb: 2 }
-end
diff --git a/app/models/fertilizer_component.rb b/app/models/fertilizer_component.rb
deleted file mode 100644
index 701ae9b..0000000
--- a/app/models/fertilizer_component.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-class FertilizerComponent < ApplicationRecord
- validates :name, presence: true
-end
diff --git a/app/models/fertilizer_composition.rb b/app/models/fertilizer_composition.rb
deleted file mode 100644
index cf2bb93..0000000
--- a/app/models/fertilizer_composition.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-class FertilizerComposition < ApplicationRecord
- belongs_to :fertilizer_product
- belongs_to :fertilizer_component
-
- validates :percent_w, numericality: { greater_than: 0, less_than_or_equal_to: 100 }
-end
diff --git a/app/models/fertilizer_product.rb b/app/models/fertilizer_product.rb
deleted file mode 100644
index e41316b..0000000
--- a/app/models/fertilizer_product.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class FertilizerProduct < ApplicationRecord
- has_many :fertilizer_compositions, dependent: :destroy
- has_many :fertilizer_components, through: :fertilizer_compositions
-
- validates :name, presence: true, uniqueness: true
- validates :purity, numericality: { greater_than: 0, less_than_or_equal_to: 100 }
-end
diff --git a/app/models/nutrient.rb b/app/models/nutrient.rb
deleted file mode 100644
index c584668..0000000
--- a/app/models/nutrient.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class Nutrient < ApplicationRecord
- validates :formula, presence: true, uniqueness: true
- validates :name, presence: true
-
- before_update { raise ActiveRecord::ReadOnlyRecord }
- before_destroy { raise ActiveRecord::ReadOnlyRecord }
-end
diff --git a/app/models/nutrient_measurement.rb b/app/models/nutrient_measurement.rb
index f1d6d5b..1139af7 100644
--- a/app/models/nutrient_measurement.rb
+++ b/app/models/nutrient_measurement.rb
@@ -1,4 +1,18 @@
class NutrientMeasurement < ApplicationRecord
+ NUTRIENT_FIELDS = %i[
+ nno3 p k ca mg s na cl si fe zn b mn cu mo nnh4
+ ].freeze
+
validates :measured_on, presence: true
validates :measured_on, uniqueness: true
+
+ def self.data_series_for(*nutrients)
+ nutrients.map do |formula|
+ { name: formula, data: self.order(:measured_on).pluck(:measured_on, formula) }
+ end
+ end
+
+ def self.nutrient_fields
+ NUTRIENT_FIELDS
+ end
end
diff --git a/app/models/nutrient_profile.rb b/app/models/nutrient_profile.rb
new file mode 100644
index 0000000..0610855
--- /dev/null
+++ b/app/models/nutrient_profile.rb
@@ -0,0 +1,13 @@
+class NutrientProfile < ApplicationRecord
+ # Align these keys with your schema columns (per your schema.txt)
+ NUTRIENT_KEYS = %i[
+ nno3 p k ca mg s na cl si fe zn b mn cu mo nnh4
+ ].freeze
+
+ # Returns a Hash of nutrient => numeric requirement (nil kept; caller can skip nils)
+ def requirements_hash
+ attributes
+ .slice(*NUTRIENT_KEYS.map(&:to_s)) # only nutrient columns
+ .transform_keys(&:to_s)
+ end
+end
diff --git a/app/models/raft.rb b/app/models/raft.rb
deleted file mode 100644
index 3fe5928..0000000
--- a/app/models/raft.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-class Raft < ApplicationRecord
- belongs_to :bed
- belongs_to :crop, optional: true
- validates :location, presence: true, uniqueness: { scope: :bed_id }
-end
diff --git a/app/models/target.rb b/app/models/target.rb
new file mode 100644
index 0000000..9211e74
--- /dev/null
+++ b/app/models/target.rb
@@ -0,0 +1,42 @@
+# app/models/target.rb
+class Target < ApplicationRecord
+ has_many :target_allocations, dependent: :destroy
+ has_many :nutrient_profiles, through: :target_allocations
+
+ accepts_nested_attributes_for :target_allocations, allow_destroy: true
+ # validate :percentages_sum_to_100
+
+ def weighted_requirements
+ totals = Hash.new(0.0)
+ denom = 100.0
+
+ target_allocations.includes(:nutrient_profile).each do |alloc|
+ profile = alloc.nutrient_profile
+ next unless profile
+
+ weight = (alloc.percentage || 0).to_f / denom
+ next if weight <= 0
+
+ # Prefer the helper, but gracefully fall back to slicing attributes.
+ reqs = if profile.respond_to?(:requirements_hash)
+ profile.requirements_hash
+ else
+ profile.attributes.slice(*NutrientProfile::NUTRIENT_KEYS.map(&:to_s))
+ end
+
+ reqs.each do |nutrient_key, value|
+ next if value.nil?
+ totals[nutrient_key.to_s] += value.to_f * weight
+ end
+ end
+
+ totals
+ end
+
+ private
+
+ # def percentages_sum_to_100
+ # sum = target_allocations.sum { |a| a.percentage.to_f }
+ # errors.add(:base, "La somme des pourcentages doit être égale à 100%") unless (sum - 100.0).abs <= 0.1
+ # end
+end
diff --git a/app/models/target_allocation.rb b/app/models/target_allocation.rb
new file mode 100644
index 0000000..6aa1dcb
--- /dev/null
+++ b/app/models/target_allocation.rb
@@ -0,0 +1,7 @@
+class TargetAllocation < ApplicationRecord
+ belongs_to :target
+ belongs_to :nutrient_profile
+
+ validates :percentage, numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 100 }
+ validates :nutrient_profile_id, uniqueness: { scope: :target_id }
+end
Copyright 2019--2025 Marius PETER