所以我正在从这个
Railscast工作.
而且,我知道Rails 4的Strong参数有一些变化.
我已经检查了我的实现四倍,但看不到我出错了.正如现在一样,在最初提交病人时(即创建方法)打勾时,勾选“破坏”框,并按照预期的方式工作,并删除任何具有复选框的药物,并允许任何不在(从三个表单输入它提供).
然而,当我随后编辑该病人时,任何未被检查被删除的药物都被复制(所以我最终得到的药物比我开始使用的更多),任何被检查的药物似乎都没有改变.
所以如果有两种药物附有“Med1”和“Med2”,我编辑病人,如果两者都被标记为删除,我仍然会以“Med1”和“Med2”结尾.如果只有“Med1”被标记为删除,我将最终得到“Med1”和“Med2”和额外的“Med2”.如果没有标记为删除,我将最终得到“Med1”和“Med2”两个.
#patient.rb class Patient < ActiveRecord::Base has_many :procedures has_many :medications,dependent: :destroy has_many :prevIoUs_operations,dependent: :destroy accepts_nested_attributes_for :medications,:allow_destroy => true,:reject_if => lambda { |a| a[:name].blank? },end
#views/patients/_form.html.erb <%= form_for(@patient) do |f| %> <% if @patient.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@patient.errors.count,"error") %> prohibited this patient from being saved:</h2> <ul> <% @patient.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <%= f.fields_for :medications do |builder| %> <%= render "medication_fields",:f => builder %> <% end %> <div class="field"> <%= f.label :first_name %><br> <%= f.text_field :first_name %> </div> <div class="field"> <%= f.label :last_name %><br> <%= f.text_field :last_name %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
#views/patients/medications_fields.html <div class="field"> <%= f.label :name %><br> <%= f.text_field :name %> </div> <div class="field"> <%= f.label :_destroy,"Remove Medication" %> <%= f.check_Box :_destroy %> </div>
#controllers/patients_controller.rb class PatientsController < ApplicationController before_action :set_patient,only: [:show,:edit,:update,:destroy] # GET /patients # GET /patients.json def index @patients = Patient.all end # GET /patients/1 # GET /patients/1.json def show end # GET /patients/new def new @patient = Patient.new 3.times { @patient.medications.build } end # GET /patients/1/edit def edit end # POST /patients # POST /patients.json def create @patient = Patient.new(patient_params) respond_to do |format| if @patient.save format.html { redirect_to @patient,notice: 'Patient was successfully created.' } format.json { render action: 'show',status: :created,location: @patient } else format.html { render action: 'new' } format.json { render json: @patient.errors,status: :unprocessable_entity } end end end # PATCH/PUT /patients/1 # PATCH/PUT /patients/1.json def update respond_to do |format| if @patient.update(patient_params) format.html { redirect_to @patient,notice: 'Patient was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @patient.errors,status: :unprocessable_entity } end end end # DELETE /patients/1 # DELETE /patients/1.json def destroy @patient.destroy respond_to do |format| format.html { redirect_to patients_url } format.json { head :no_content } end flash[:notice] = "Patient was successfully deleted." end private # Never trust parameters from the scary internet,only allow the white list through. def patient_params params.require(:patient).permit(:first_name,:last_name,medications_attributes: [:name,:_destroy]) end end
我一直非常小心,检查了一百万次:_destroy标志被允许通过强大的参数,但仍然没有骰子.
任何帮助赞赏,必须是明显的,我只是看不到.
编辑
改变这个…
# Never trust parameters from the scary internet,:_destroy]) end
到这个…
# Never trust parameters from the scary internet,only allow the white list through. def patient_params params.require(:patient).permit! end
似乎工作正常,所以我仍然确定这是与强参数有关,但后者是不太安全,我敢肯定,而不是最佳实践.
解决方法
当你在做什么
# Never trust parameters from the scary internet,only allow the white list through. def patient_params params.require(:patient).permit! end
它允许您的所有属性,不推荐.这更像是一个黑客而不是解决方案.
如果你看你的问题
如果你看看你允许的参数
# Never trust parameters from the scary internet,only allow the white list through. def patient_params params.require(:patient).permit(:first_name,:_destroy]) end
这将有助于创建病人,但不会更新或编辑他们,因为当您创建新记录时,它不需要您允许ID,但是当您想要更新或编辑记录时,您需要其ID被允许.
固定:
# Never trust parameters from the scary internet,only allow the white list through. def patient_params params.require(:patient).permit(:id,:first_name,medications_attributes: [:id,:name,:_destroy]) end