Properly implement bed and raft management logic.

Commit
075665c588989ed0decdfb20d83f32b33eed4639
Author
Marius Peter <marius.peter@tutanota.com>
Author date
Committer
Marius Peter <marius.peter@tutanota.com>
Committer date
Changed files
app/controllers/beds_controller.rb
index 00000000..c2139786 000000..100644
@@ -0,0 +1,61 @@
1 Added: class BedsController < ApplicationController
2 Added: before_action :set_bed, only: %i[ edit update ]
3 Added: before_action :get_crops, only: %i[ index edit update ]
4 Added:
5 Added: def index
6 Added: @beds = Bed.all
7 Added: end
8 Added:
9 Added: def edit
10 Added: end
11 Added:
12 Added: def update
13 Added: if @bed.update(bed_params)
14 Added: redirect_to beds_path, notice: "Bed #{@bed.id} successfully updated."
15 Added: else
16 Added: render :edit, status: :unprocessable_entity
17 Added: end
18 Added: end
19 Added:
20 Added: def bulk_assign_crops
21 Added: crop = Crop.find(params[:crop_id])
22 Added: Raft.update_all(crop_id: crop.id)
23 Added: redirect_back fallback_location: root_path, notice: "All rafts set to #{crop.name}."
24 Added: end
25 Added:
26 Added:
27 Added: def reset_seed_crops
28 Added: # mirrors seed logic
29 Added: tomatoes = Crop.find_by!(name: :tomatoes)
30 Added: chives = Crop.find_by!(name: :chives)
31 Added: lettuce = Crop.find_by!(name: :lettuce)
32 Added:
33 Added: Bed.includes(:rafts).find_each do |bed|
34 Added: default_crop =
35 Added: case bed.location
36 Added: when 1..3 then tomatoes
37 Added: when 4..7 then chives
38 Added: else lettuce
39 Added: end
40 Added: bed.rafts.update_all(crop_id: default_crop.id)
41 Added: end
42 Added: redirect_back fallback_location: root_path, notice: "Raft crops reset to default seed layout."
43 Added: end
44 Added:
45 Added: private
46 Added:
47 Added: def set_bed
48 Added: @bed = Bed.find(params[:id])
49 Added: end
50 Added:
51 Added: def get_crops
52 Added: @crops = Crop.order(:name)
53 Added: end
54 Added:
55 Added: def bed_params
56 Added: params.require(:bed).permit(
57 Added: :location,
58 Added: rafts_attributes: %i[id crop_id]
59 Added: )
60 Added: end
61 Added: end
app/controllers/crops_controller.rb
index 96198522..951d3805 100644..100644
@@ -1,40 +1,30 @@
1 1 class CropsController < ApplicationController
2 2 before_action :set_crop, only: %i[ show edit update destroy ]
3 3
4 Removed: # GET /crops or /crops.json
5 4 def index
6 5 @crops = Crop.all
7 6 end
8 7
9 Removed: # GET /crops/1 or /crops/1.json
10 8 def show
11 9 end
12 10
13 Removed: # GET /crops/new
14 11 def new
15 12 @crop = Crop.new
16 13 end
17 14
18 Removed: # GET /crops/1/edit
19 15 def edit
20 16 end
21 17
22 Removed: # POST /crops or /crops.json
23 18 def create
24 19 @crop = Crop.new(crop_params)
25 20
26 Removed: respond_to do |format|
27 Removed: if @crop.save
28 Removed: format.html { redirect_to @crop, notice: "Crop was successfully created." }
29 Removed: format.json { render :show, status: :created, location: @crop }
30 Removed: else
31 Removed: format.html { render :new, status: :unprocessable_entity }
32 Removed: format.json { render json: @crop.errors, status: :unprocessable_entity }
33 Removed: end
21 Added: if @crop.save
22 Added: redirect_to @crop, notice: "Crop was successfully created."
23 Added: else
24 Added: render :new, status: :unprocessable_entity
34 25 end
35 26 end
36 27
37 Removed: # PATCH/PUT /crops/1 or /crops/1.json
38 28 def update
39 29 respond_to do |format|
40 30 if @crop.update(crop_params)
@@ -47,7 +37,6 @@
47 37 end
48 38 end
49 39
50 Removed: # DELETE /crops/1 or /crops/1.json
51 40 def destroy
52 41 @crop.destroy!
53 42
@@ -58,13 +47,12 @@
58 47 end
59 48
60 49 private
61 Removed: # Use callbacks to share common setup or constraints between actions.
62 Removed: def set_crop
63 Removed: @crop = Crop.find(params.expect(:id))
64 Removed: end
65 50
66 Removed: # Only allow a list of trusted parameters through.
67 Removed: def crop_params
68 Removed: params.expect(crop: [ :name, :crop_type, :nno3, :p, :k, :ca, :mg, :s, :na, :cl, :si, :fe, :zn, :b, :mn, :cu, :mo, :nnh4 ])
69 Removed: end
51 Added: def set_crop
52 Added: @crop = Crop.find(params.expect(:id))
53 Added: end
54 Added:
55 Added: def crop_params
56 Added: params.expect(crop: [ :name, :crop_type, :nno3, :p, :k, :ca, :mg, :s, :na, :cl, :si, :fe, :zn, :b, :mn, :cu, :mo, :nnh4 ])
57 Added: end
70 58 end
app/controllers/rafts_controller.rb
index 96d99fd3..c1c8a72c 100644..100644
@@ -1,54 +1,29 @@
1 1 class RaftsController < ApplicationController
2 Removed: before_action :set_collections, only: [ :editor ]
2 Added: before_action :set_raft, only: %i[ edit update ]
3 Added: before_action :set_crop, only: %i[ edit update ]
3 4
4 Removed: def index
5 Removed: redirect_to editor_rafts_path
5 Added: def edit
6 6 end
7 7
8 Removed: def editor
9 Removed: # @beds, @crops set in before_action
10 Removed: end
11 Removed:
12 Removed: # 1) Assign ALL rafts
13 Removed: def assign_all
14 Removed: crop_id = normalized_crop_id(params[:crop_id])
15 Removed: Raft.update_all(crop_id: crop_id) # nil ok
16 Removed: redirect_to editor_rafts_path, notice: "All rafts updated."
17 Removed: end
18 Removed:
19 Removed: # 2) Assign all rafts in ONE bed
20 Removed: def assign_bed
21 Removed: bed = Bed.find(params.require(:bed_id))
22 Removed: crop_id = normalized_crop_id(params[:crop_id])
23 Removed: bed.rafts.update_all(crop_id: crop_id)
24 Removed: redirect_to editor_rafts_path, notice: "Bed ##{bed.location} updated."
25 Removed: end
26 Removed:
27 Removed: # 3) Assign ONE raft
28 Removed: def assign_one
29 Removed: raft = Raft.find(params[:id])
30 Removed: val = params[:crop_id].to_s
31 Removed:
32 Removed: if val.blank? || val.casecmp("null").zero?
33 Removed: # Skip validations; write NULL directly
34 Removed: raft.update_column(:crop_id, nil)
8 Added: def update
9 Added: if @raft.update(raft_params)
10 Added: redirect_to beds_path, notice: "Raft #{@raft.id} successfully updated."
35 11 else
36 Removed: raft.update!(crop_id: val)
12 Added: render :edit, status: :unprocessable_entity
37 13 end
38 Removed:
39 Removed: redirect_to editor_rafts_path(anchor: "bed-#{raft.bed_id}"), notice: "Raft updated."
40 14 end
41 15
42 16 private
43 17
44 Removed: def set_collections
45 Removed: @beds = Bed.order(:location)
18 Added: def set_raft
19 Added: @raft = Raft.find(params[:id])
20 Added: end
21 Added:
22 Added: def set_crop
46 23 @crops = Crop.order(:name)
47 24 end
48 25
49 Removed: # Accept "", "null" → nil to allow clearing
50 Removed: def normalized_crop_id(val)
51 Removed: return nil if val.blank? || val.to_s.downcase == "null"
52 Removed: val
26 Added: def raft_params
27 Added: params.require(:raft).permit(:location, :bed_id, :crop_id)
53 28 end
54 29 end
app/helpers/beds_helper.rb
index 00000000..2f3e2cba 000000..100644
@@ -0,0 +1,2 @@
1 Added: module BedsHelper
2 Added: end
app/models/bed.rb
index 33eafd23..d41afe68 100644..100644
@@ -1,4 +1,5 @@
1 1 class Bed < ApplicationRecord
2 2 has_many :rafts, -> { order(:location) }, dependent: :destroy
3 Added: accepts_nested_attributes_for :rafts
3 4 validates :location, presence: true, uniqueness: true
4 5 end
app/models/raft.rb
index af527003..3fe59282 100644..100644
@@ -1,5 +1,5 @@
1 1 class Raft < ApplicationRecord
2 2 belongs_to :bed
3 Removed: belongs_to :crop
3 Added: belongs_to :crop, optional: true
4 4 validates :location, presence: true, uniqueness: { scope: :bed_id }
5 5 end
app/views/application/_navbar.html.erb
index 9fa250a2..89dfe3d9 100644..100644
@@ -3,12 +3,12 @@
3 3 <span class="navbar-brand">FAPG</span>
4 4
5 5 <button class="navbar-toggler"
6 Removed: type="button"
7 Removed: data-bs-toggle="collapse"
8 Removed: data-bs-target="#navbarSupportedContent"
9 Removed: aria-controls="navbarSupportedContent"
10 Removed: aria-expanded="false"
11 Removed: aria-label="Toggle navigation">
6 Added: type="button"
7 Added: data-bs-toggle="collapse"
8 Added: data-bs-target="#navbarSupportedContent"
9 Added: aria-controls="navbarSupportedContent"
10 Added: aria-expanded="false"
11 Added: aria-label="Toggle navigation">
12 12 <span class="navbar-toggler-icon"></span>
13 13 </button>
14 14
app/views/beds/_bed.html.erb
index 00000000..6961f9bd 000000..100644
@@ -0,0 +1,2 @@
1 Added: <div id="<%= dom_id bed %>">
2 Added: </div>
app/views/beds/_form.html.erb
index 00000000..e3a5c356 000000..100644
@@ -0,0 +1,28 @@
1 Added: <%= form_with(model: bed) do |form| %>
2 Added: <% if bed.errors.any? %>
3 Added: <div style="color: red">
4 Added: <h2><%= pluralize(bed.errors.count, "error") %> prohibited this bed from being saved:</h2>
5 Added: <ul>
6 Added: <% bed.errors.each do |error| %>
7 Added: <li><%= error.full_message %></li>
8 Added: <% end %>
9 Added: </ul>
10 Added: </div>
11 Added: <% end %>
12 Added:
13 Added: <div class="my-3">
14 Added: <%= form.fields_for :rafts do |raft| %>
15 Added: <div class="input-group input-group-sm my-2">
16 Added: <span class="input-group-text">Raft <%= raft.object.location %></span>
17 Added: <%= raft.collection_select :crop_id, @crops, :id, :name,
18 Added: { include_blank: "Unassigned" },
19 Added: { class: "form-select" } %>
20 Added: </div>
21 Added: <%= raft.hidden_field :id %>
22 Added: <% end %>
23 Added: </div>
24 Added:
25 Added: <div>
26 Added: <%= form.submit class: "btn btn-primary" %>
27 Added: </div>
28 Added: <% end %>
app/views/beds/edit.html.erb
index 00000000..68875862 000000..100644
@@ -0,0 +1,11 @@
1 Added: <% content_for :title, "Editing bed #{@bed.location}" %>
2 Added:
3 Added: <h1 class="display-1">Editing bed <%= @bed.location %></h1>
4 Added:
5 Added: <%= render "form", bed: @bed %>
6 Added:
7 Added: <br>
8 Added:
9 Added: <div>
10 Added: <%= link_to "Back to beds", beds_path, class: "btn btn-secondary" %>
11 Added: </div>
app/views/beds/index.html.erb
index 00000000..e645dc51 000000..100644
@@ -0,0 +1,54 @@
1 Added: <% content_for :title, "Crop Allocation" %>
2 Added:
3 Added: <h1 class="display-1">Beds and Rafts</h1>
4 Added:
5 Added: <%= link_to "Back to dashboard", root_path, class: "btn btn-outline-secondary my-3" %>
6 Added:
7 Added:
8 Added: <p>
9 Added: Click on a bed row or an individual raft to update the corresponding crop.
10 Added: </p>
11 Added:
12 Added: <%= form_with url: bulk_assign_crops_beds_path,
13 Added: method: :patch,
14 Added: local: true do %>
15 Added: <div class="btn-group" role="group" aria-label="Raft crop bulk actions">
16 Added: <select class="form-select" name="crop_id">
17 Added: <% @crops.each do |crop| %>
18 Added: <option value="<%= crop.id %>"><%= crop.name.titleize %></option>
19 Added: <% end %>
20 Added: </select>
21 Added: <button type="submit" class="btn btn-outline-primary">Apply to all</button>
22 Added: </div>
23 Added: <% end %>
24 Added:
25 Added: <div class="table-responsive">
26 Added: <table class="table table-sm small text-center align-middle my-3">
27 Added: <thead>
28 Added: <tr>
29 Added: <th>Bed</th>
30 Added: <% max_cols = @beds.map { |b| b.rafts.count }.max %>
31 Added: <% (1..max_cols).each do |i| %>
32 Added: <th>R<%= i %></th>
33 Added: <% end %>
34 Added: </tr>
35 Added: </thead>
36 Added: <tbody>
37 Added: <% @beds.each do |bed| %>
38 Added: <tr>
39 Added: <th><%= link_to bed.location, edit_bed_path(bed), class: "btn btn-outline-secondary" %></th>
40 Added: <% bed.rafts.each do |raft| %>
41 Added: <td>
42 Added: <%= link_to (raft&.crop&.name || "—"), edit_raft_path(raft), class: "btn btn-sm" %>
43 Added: </td>
44 Added: <% end %>
45 Added: </tr>
46 Added: <% end %>
47 Added: </tbody>
48 Added: </table>
49 Added: </div>
50 Added:
51 Added: <%= button_to "Reset crop allocation", reset_seed_crops_beds_path,
52 Added: method: :post,
53 Added: form: { data: { turbo: false } },
54 Added: class: "btn btn-outline-danger" %>
app/views/dashboard/_nutrient_measurements.html.erb
index 00000000..bc63a607 000000..100644
@@ -0,0 +1,22 @@
1 Added: <div class="card shadow mb-4">
2 Added: <div class="card-header d-flex justify-content-between align-items-center">
3 Added: <h5 class="mb-0">Nutrient Measurements</h5>
4 Added: <div class="btn-group">
5 Added: <%#= link_to "Add new measurement", editor_rafts_path, class: "btn btn-sm btn-primary" %>
6 Added: <%#= link_to "View all", editor_rafts_path, class: "btn btn-sm btn-secondary" %>
7 Added: </div>
8 Added: </div>
9 Added:
10 Added: <div class="card-body p-0">
11 Added: <div class="container mb-3">
12 Added: <%= line_chart @npk_measurement_data,
13 Added: title: "NPK",
14 Added: ytitle: "Concentration (mg/L)" %>
15 Added: </div>
16 Added: <div class="container mb-3">
17 Added: <%= line_chart @ammonium_measurement_data,
18 Added: title: "Ammonium",
19 Added: ytitle: "Concentration (mg/L)" %>
20 Added: </div>
21 Added: </div>
22 Added: </div>
app/views/dashboard/_raft_allocation.html.erb
index ef95cddb..a2128ea2 100644..100644
@@ -1,7 +1,7 @@
1 1 <div class="card shadow mb-4">
2 2 <div class="card-header d-flex justify-content-between align-items-center">
3 Removed: <h5 class="mb-0">Raft Allocation</h5>
4 Removed: <%= link_to "Edit raft allocation", editor_rafts_path, class: "btn btn-sm btn-primary" %>
3 Added: <h5 class="mb-0">Crop Allocation</h5>
4 Added: <%= link_to "Edit allocation", beds_path, class: "btn btn-sm btn-primary" %>
5 5 </div>
6 6
7 7 <%= bar_chart @raft_data, stacked: true %>
app/views/dashboard/_recent_measurements.html.erb
index bc63a607..00000000 100644..000000
@@ -1,22 +0,0 @@
1 Removed: <div class="card shadow mb-4">
2 Removed: <div class="card-header d-flex justify-content-between align-items-center">
3 Removed: <h5 class="mb-0">Nutrient Measurements</h5>
4 Removed: <div class="btn-group">
5 Removed: <%#= link_to "Add new measurement", editor_rafts_path, class: "btn btn-sm btn-primary" %>
6 Removed: <%#= link_to "View all", editor_rafts_path, class: "btn btn-sm btn-secondary" %>
7 Removed: </div>
8 Removed: </div>
9 Removed:
10 Removed: <div class="card-body p-0">
11 Removed: <div class="container mb-3">
12 Removed: <%= line_chart @npk_measurement_data,
13 Removed: title: "NPK",
14 Removed: ytitle: "Concentration (mg/L)" %>
15 Removed: </div>
16 Removed: <div class="container mb-3">
17 Removed: <%= line_chart @ammonium_measurement_data,
18 Removed: title: "Ammonium",
19 Removed: ytitle: "Concentration (mg/L)" %>
20 Removed: </div>
21 Removed: </div>
22 Removed: </div>
app/views/dashboard/index.html.erb
index 2902ada3..b1b2d87c 100644..100644
@@ -4,4 +4,4 @@
4 4
5 5 <%= render "target_table" %>
6 6
7 Removed: <%= render "recent_measurements" %>
7 Added: <%= render "nutrient_measurements" %>
app/views/rafts/_form.html.erb
index 00000000..7b5d382d 000000..100644
@@ -0,0 +1,23 @@
1 Added: <%= form_with(model: raft) do |form| %>
2 Added: <% if raft.errors.any? %>
3 Added: <div style="color: red">
4 Added: <h2><%= pluralize(bed.errors.count, "error") %> prohibited this raft from being saved:</h2>
5 Added:
6 Added: <ul>
7 Added: <% raft.errors.each do |error| %>
8 Added: <li><%= error.full_message %></li>
9 Added: <% end %>
10 Added: </ul>
11 Added: </div>
12 Added: <% end %>
13 Added:
14 Added: <div class="my-3">
15 Added: <label class="form-label">Crop</label>
16 Added: <%= form.collection_select :crop_id, @crops, :id, :name,
17 Added: { include_blank: "Unassigned" }, { class: "form-select" } %>
18 Added: </div>
19 Added:
20 Added: <div>
21 Added: <%= form.submit class: "btn btn-primary" %>
22 Added: </div>
23 Added: <% end %>
app/views/rafts/edit.html.erb
index 00000000..bf975dc5 000000..100644
@@ -0,0 +1,5 @@
1 Added: <% content_for :title, "Editing bed #{@raft.bed.location}, raft #{@raft.location}" %>
2 Added:
3 Added: <h1 class="display-1">Editing bed <%= @raft.bed.location %>, raft <%= @raft.location %></h1>
4 Added:
5 Added: <%= render "form", raft: @raft %>
app/views/rafts/editor.html.erb
index cde56d8a..00000000 100644..000000
@@ -1,108 +0,0 @@
1 Removed: <div class="d-flex justify-content-between align-items-center mb-3">
2 Removed: <h1 class="display-1">Rafts editor</h1>
3 Removed: <%= link_to "Back to dashboard", root_path, class: "btn btn-outline-secondary" %>
4 Removed: </div>
5 Removed:
6 Removed: <!-- Bulk assign all rafts -->
7 Removed: <div class="card">
8 Removed: <div class="card-header">Assign ALL rafts</div>
9 Removed: <div class="card-body">
10 Removed: <%= form_with url: assign_all_rafts_path, method: :patch, class: "row g-2", data: { turbo: false } do %>
11 Removed: <div class="col-12 col-md-6">
12 Removed: <select class="form-select" name="crop_id">
13 Removed: <option value="">— Unassigned (clear) —</option>
14 Removed: <% @crops.each do |crop| %>
15 Removed: <option value="<%= crop.id %>"><%= crop.name %></option>
16 Removed: <% end %>
17 Removed: </select>
18 Removed: </div>
19 Removed: <div class="col-12 col-md-auto">
20 Removed: <button class="btn btn-primary">Apply to all</button>
21 Removed: </div>
22 Removed: <% end %>
23 Removed: </div>
24 Removed: </div>
25 Removed:
26 Removed: <div class="table-responsive">
27 Removed: <table class="table table-sm table-striped text-center align-middle my-3">
28 Removed: <thead>
29 Removed: <tr>
30 Removed: <th class="text-start">Bed</th>
31 Removed: <% max_cols = @beds.map { |b| b.rafts.count }.max %>
32 Removed: <% (1..max_cols).each do |i| %>
33 Removed: <th>R<%= i %></th>
34 Removed: <% end %>
35 Removed: </tr>
36 Removed: </thead>
37 Removed: <tbody>
38 Removed: <% @beds.each do |bed| %>
39 Removed: <tr>
40 Removed: <th><%= bed.location %></th>
41 Removed: <% bed.rafts.order(:location).each do |raft| %>
42 Removed: <td>
43 Removed: <% if raft.crop %>
44 Removed: <%= raft.crop.name %>
45 Removed: <% else %>
46 Removed:
47 Removed: <% end %>
48 Removed: </td>
49 Removed: <% end %>
50 Removed: </tr>
51 Removed: <% end %>
52 Removed: </tbody>
53 Removed: </table>
54 Removed: </div>
55 Removed:
56 Removed: <!-- Per-bed tables -->
57 Removed: <% @beds.each do |bed| %>
58 Removed: <div class="card mb-3" id="bed-<%= bed.id %>">
59 Removed: <div class="card-header d-flex flex-wrap gap-2 align-items-center">
60 Removed: <span class="me-auto">Bed <strong>#<%= bed.location %></strong></span>
61 Removed: <%= form_with url: assign_bed_rafts_path, method: :patch, class: "d-flex gap-2 align-items-center", data: { turbo: false } do %>
62 Removed: <input type="hidden" name="bed_id" value="<%= bed.id %>">
63 Removed: <select class="form-select" name="crop_id">
64 Removed: <option value="">— Unassigned (clear) —</option>
65 Removed: <% @crops.each do |crop| %>
66 Removed: <option value="<%= crop.id %>"><%= crop.name %></option>
67 Removed: <% end %>
68 Removed: </select>
69 Removed: <button class="btn btn-primary">Apply</button>
70 Removed: <% end %>
71 Removed: </div>
72 Removed: <div class="card-body p-0">
73 Removed: <div class="table-responsive">
74 Removed: <table class="table table-sm mb-0 align-middle">
75 Removed: <thead class="table-light">
76 Removed: <tr>
77 Removed: <th class="text-nowrap text-center">Raft</th>
78 Removed: <th>Crop</th>
79 Removed: <th class="text-end">Actions</th>
80 Removed: </tr>
81 Removed: </thead>
82 Removed: <tbody>
83 Removed: <% bed.rafts.order(:location).each do |raft| %>
84 Removed: <tr>
85 Removed: <td class="text-center"><strong><%= raft.location %></strong></td>
86 Removed: <td style="max-width: 280px;">
87 Removed: <%= form_with url: assign_one_raft_path(raft), method: :patch, class: "d-flex gap-2", data: { turbo: false } do %>
88 Removed: <select class="form-select" name="crop_id">
89 Removed: <option value="">— Unassigned (clear) —</option>
90 Removed: <% @crops.each do |crop| %>
91 Removed: <option value="<%= crop.id %>" <%= "selected" if raft.crop_id == crop.id %>><%= crop.name %></option>
92 Removed: <% end %>
93 Removed: </select>
94 Removed: <button class="btn btn-outline-primary">Save</button>
95 Removed: <% end %>
96 Removed: </td>
97 Removed: <td class="text-end">
98 Removed: <%= button_to "Clear", assign_one_raft_path(raft, crop_id: ""), method: :patch,
99 Removed: form: { data: { turbo: false } }, class: "btn btn-outline-secondary btn-sm" %>
100 Removed: </td>
101 Removed: </tr>
102 Removed: <% end %>
103 Removed: </tbody>
104 Removed: </table>
105 Removed: </div>
106 Removed: </div>
107 Removed: </div>
108 Removed: <% end %>
config/routes.rb
index 1b24155c..1dd57b51 100644..100644
@@ -2,18 +2,17 @@
2 2 root "dashboard#index"
3 3
4 4 get "ferti_recipe", to: "recipes#show"
5 Removed: resources :fertilizer_products
6 Removed: resources :raft_crops, only: [ :update ]
7 Removed: resources :rafts, only: [ :index ] do
5 Added:
6 Added: resources :beds, only: [ :index, :edit, :update ] do
8 7 collection do
9 Removed: get :editor # rafts/editor
10 Removed: patch :assign_all # bulk assign all rafts
11 Removed: patch :assign_bed # bulk assign per bed
8 Added: patch :bulk_assign_crops
9 Added: post :reset_seed_crops
12 10 end
13 Removed: member do
14 Removed: patch :assign_one # per raft
15 Removed: end
11 Added:
12 Added: resources :rafts, only: [ :index, :edit, :update ], shallow: true
16 13 end
14 Added:
15 Added: resources :fertilizer_products
17 16 resources :crops
18 17 resources :nutrient_measurements
19 18
db/seeds/3_crops.rb
index 2957188b..6a5c10fc 100644..100644
@@ -104,17 +104,17 @@
104 104 }
105 105
106 106 [
107 Removed: [ "lettuce", 0, LEAFY ],
108 Removed: [ "kale", 0, LEAFY ],
109 Removed: [ "chinese cabbage", 0, LEAFY ],
110 Removed: [ "tomatoes", 1, TOMATO ],
111 Removed: [ "raspberries", 1, RASPBERRY ],
112 Removed: [ "strawberries", 1, STRAWBERRY ],
113 Removed: [ "hot peppers", 1, HOT_PEPPER ],
114 Removed: [ "parsley", 2, HERB ],
115 Removed: [ "chives", 2, HERB ],
116 Removed: [ "italian basil", 2, HERB ],
117 Removed: [ "dill", 2, HERB ]
107 Added: [ "lettuce", 0, LEAFY ],
108 Added: [ "kale", 0, LEAFY ],
109 Added: [ "cabbage, chinese", 0, LEAFY ],
110 Added: [ "tomatoes", 1, TOMATO ],
111 Added: [ "raspberries", 1, RASPBERRY ],
112 Added: [ "strawberries", 1, STRAWBERRY ],
113 Added: [ "hot peppers", 1, HOT_PEPPER ],
114 Added: [ "parsley", 2, HERB ],
115 Added: [ "chives", 2, HERB ],
116 Added: [ "italian basil", 2, HERB ],
117 Added: [ "dill", 2, HERB ]
118 118 ].each do |name, type, nutrient_requirements|
119 119 Crop.find_or_create_by!(name: name) do |c|
120 120 c.crop_type = type
db/seeds/4_beds_and_rafts.rb
index 01052602..1cd95dcb 100644..100644
@@ -9,7 +9,7 @@
9 9 when 3 then "hot peppers"
10 10 when 4 then "chives"
11 11 when 5 then "italian basil"
12 Removed: when 6..7 then "chinese cabbage"
12 Added: when 6..7 then "cabbage, chinese"
13 13 else "lettuce"
14 14 end
15 15
test/controllers/beds_controller_test.rb
index 00000000..7afd166a 000000..100644
@@ -0,0 +1,48 @@
1 Added: require "test_helper"
2 Added:
3 Added: class BedsControllerTest < ActionDispatch::IntegrationTest
4 Added: setup do
5 Added: @bed = beds(:one)
6 Added: end
7 Added:
8 Added: test "should get index" do
9 Added: get beds_url
10 Added: assert_response :success
11 Added: end
12 Added:
13 Added: test "should get new" do
14 Added: get new_bed_url
15 Added: assert_response :success
16 Added: end
17 Added:
18 Added: test "should create bed" do
19 Added: assert_difference("Bed.count") do
20 Added: post beds_url, params: { bed: {} }
21 Added: end
22 Added:
23 Added: assert_redirected_to bed_url(Bed.last)
24 Added: end
25 Added:
26 Added: test "should show bed" do
27 Added: get bed_url(@bed)
28 Added: assert_response :success
29 Added: end
30 Added:
31 Added: test "should get edit" do
32 Added: get edit_bed_url(@bed)
33 Added: assert_response :success
34 Added: end
35 Added:
36 Added: test "should update bed" do
37 Added: patch bed_url(@bed), params: { bed: {} }
38 Added: assert_redirected_to bed_url(@bed)
39 Added: end
40 Added:
41 Added: test "should destroy bed" do
42 Added: assert_difference("Bed.count", -1) do
43 Added: delete bed_url(@bed)
44 Added: end
45 Added:
46 Added: assert_redirected_to beds_url
47 Added: end
48 Added: end
test/fixtures/beds.yml
index 330db855..d7a33292 100644..100644
@@ -1,7 +1,11 @@
1 1 # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2 2
3 Removed: one:
4 Removed: number: 1
5 Removed:
6 Removed: two:
7 Removed: number: 1
3 Added: # This model initially had no columns defined. If you add columns to the
4 Added: # model remove the "{}" from the fixture names and add the columns immediately
5 Added: # below each fixture, per the syntax in the comments below
6 Added: #
7 Added: one: {}
8 Added: # column: value
9 Added: #
10 Added: two: {}
11 Added: # column: value
test/system/beds_test.rb
index 00000000..b5e6a86e 000000..100644
@@ -0,0 +1,39 @@
1 Added: require "application_system_test_case"
2 Added:
3 Added: class BedsTest < ApplicationSystemTestCase
4 Added: setup do
5 Added: @bed = beds(:one)
6 Added: end
7 Added:
8 Added: test "visiting the index" do
9 Added: visit beds_url
10 Added: assert_selector "h1", text: "Beds"
11 Added: end
12 Added:
13 Added: test "should create bed" do
14 Added: visit beds_url
15 Added: click_on "New bed"
16 Added:
17 Added: click_on "Create Bed"
18 Added:
19 Added: assert_text "Bed was successfully created"
20 Added: click_on "Back"
21 Added: end
22 Added:
23 Added: test "should update Bed" do
24 Added: visit bed_url(@bed)
25 Added: click_on "Edit this bed", match: :first
26 Added:
27 Added: click_on "Update Bed"
28 Added:
29 Added: assert_text "Bed was successfully updated"
30 Added: click_on "Back"
31 Added: end
32 Added:
33 Added: test "should destroy Bed" do
34 Added: visit bed_url(@bed)
35 Added: click_on "Destroy this bed", match: :first
36 Added:
37 Added: assert_text "Bed was successfully destroyed"
38 Added: end
39 Added: end