Rails关联模型表单开发:大学生患者应用报告表单创建需求
Hey there! Let's tackle building that patient report form for your Rails-based patient management app. Based on the model snippet you shared, here's a practical, step-by-step approach:
First, let's wrap up your Patient model's association—you had has_m... which I'm guessing is has_many :reports (since one patient can have multiple reports). Here's your updated Patient model code:
class Patient < ActiveRecord::Base include Tire::Model::Search include Tire::Model::Callbacks validates :name, presence:true validates :age, presence:true validates :phone, presence:true validates :ailment, presence:true validates :apointment, presence:true # Quick note: typo here, should be `appointment` validates :status, presence:true belongs_to :user has_many :reports, dependent: :destroy # Add this to complete the association end
Next, create your Report model (if you haven't already) with the necessary associations and validations. Run this generator command in your terminal:
rails generate model Report patient:references user:references findings:text date:date status:string rails db:migrate
Then update the Report model to add validations:
class Report < ActiveRecord::Base belongs_to :patient belongs_to :user validates :findings, presence: true validates :date, presence: true validates :status, presence: true end
You have two solid options here: a standalone report form, or a nested form directly on a patient's profile page. Let's cover both.
Option A: Standalone Report Form
In app/views/reports/new.html.erb, use form_for to create a report tied to a specific patient (you'll pass the patient ID via the URL):
<h1>Create New Report for <%= @patient.name %></h1> <%= form_for @report do |f| %> <% if @report.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@report.errors.count, "error") %> prohibited this report from being saved:</h2> <ul> <% @report.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <%= f.hidden_field :patient_id, value: @patient.id %> <%= f.hidden_field :user_id, value: current_user.id %> # Assuming you're using Devise for authentication <div class="field"> <%= f.label :date %> <%= f.date_field :date, class: "form-control" %> </div> <div class="field"> <%= f.label :findings %> <%= f.text_area :findings, rows: 5, class: "form-control" %> </div> <div class="field"> <%= f.label :status %> <%= f.text_field :status, class: "form-control" %> </div> <div class="actions"> <%= f.submit "Save Report", class: "btn btn-primary" %> </div> <% end %>
Update your ReportsController to set the patient in the new action:
class ReportsController < ApplicationController def new @patient = Patient.find(params[:patient_id]) @report = @patient.reports.new end def create @patient = Patient.find(params[:report][:patient_id]) @report = @patient.reports.new(report_params) @report.user = current_user if @report.save redirect_to @patient, notice: 'Report was successfully created.' else render :new end end private def report_params params.require(:report).permit(:date, :findings, :status, :patient_id) end end
Option B: Nested Report Form (On Patient Show Page)
If you want to let users create a report directly from a patient's profile, use nested attributes. First, update your Patient model to accept nested attributes for reports:
class Patient < ActiveRecord::Base # ... existing code ... has_many :reports, dependent: :destroy accepts_nested_attributes_for :reports, allow_destroy: true end
Then add the nested form to app/views/patients/show.html.erb:
<h2>Add New Report</h2> <%= form_for [@patient, @patient.reports.new] do |f| %> <div class="field"> <%= f.label :date %> <%= f.date_field :date, class: "form-control" %> </div> <div class="field"> <%= f.label :findings %> <%= f.text_area :findings, rows: 3, class: "form-control" %> </div> <div class="field"> <%= f.label :status %> <%= f.text_field :status, class: "form-control" %> </div> <%= f.hidden_field :user_id, value: current_user.id %> <div class="actions"> <%= f.submit "Add Report", class: "btn btn-success" %> </div> <% end %>
Update your PatientsController to permit nested attributes (if needed):
class PatientsController < ApplicationController # ... existing code ... private def patient_params params.require(:patient).permit(:name, :age, :phone, :ailment, :appointment, :status, :user_id, reports_attributes: [:date, :findings, :status, :user_id]) end end
Don't forget to show a patient's existing reports on their show page. Add this to app/views/patients/show.html.erb:
<h2>Patient Reports</h2> <% if @patient.reports.any? %> <table class="table"> <thead> <tr> <th>Date</th> <th>Status</th> <th>Created By</th> <th>Actions</th> </tr> </thead> <tbody> <% @patient.reports.each do |report| %> <tr> <td><%= report.date.strftime("%Y-%m-%d") %></td> <td><%= report.status %></td> <td><%= report.user.name %></td> <td> <%= link_to "View", report_path(report), class: "btn btn-sm btn-info" %> <%= link_to "Edit", edit_report_path(report), class: "btn btn-sm btn-warning" %> </td> </tr> <% end %> </tbody> </table> <% else %> <p>No reports found for this patient yet.</p> <% end %>
Quick side note: I noticed a typo in your Patient model—apointment should be appointment to avoid confusion later!
内容的提问来源于stack exchange,提问作者user9277589

