ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 nested-attributes

ruby on rails - Rails 4 borra atributos anidados, funciona en crear pero no en editar/actualizar



ruby-on-rails ruby-on-rails-3 (1)

cuando estas haciendo

# Never trust parameters from the scary internet, only allow the white list through. def patient_params params.require(:patient).permit! end

Permite todos tus atributos y no es recomendable . Es más un hack que una solución.

Si miras tu pregunta

Rails 4 deleting nested attributes, works on create but not on edit/update

y si miras a tus params permitidos

# 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

Esto funcionará para crear pacientes, pero no para actualizarlos o editarlos, porque cuando creas un nuevo registro, no es necesario que permitas la identificación, pero cuando quieres actualizar o editar un registro también necesitas que se permita su identificación .

Fijar:

Simplemente pase el atributo id a los atributos permitidos y funcionará para usted

# Never trust parameters from the scary internet, only allow the white list through. def patient_params params.require(:patient).permit(:id, :first_name, :last_name, medications_attributes: [:id,:name, :_destroy]) end

Así que estoy trabajando desde este Railscast .

Y soy consciente de que ha habido algunos cambios en Rails 4 para los parámetros Strong.

Primera pregunta relevante .

Segunda pregunta relevante

He revisado cuádruple mi implementación, pero no puedo ver dónde me equivoco. Tal como está en este momento, marcar la casilla "destruir" cuando se envía al paciente inicialmente (es decir, el método de creación) funciona según lo previsto, y eliminará cualquier medicamento que tenga una casilla marcada y permitirá que no lo haga (de las tres entradas del formulario proporciona).

Sin embargo, cuando posteriormente edito a ese paciente, todos los medicamentos que no se verifican para ser eliminados se duplican (por lo que termino con más medicamentos adjuntos de los que comencé), y los que se verifican para su eliminación no parecen cambiar.

Entonces, si hay dos medicamentos adjuntos "Med1" y "Med2", y edito al paciente, si ambos están marcados para su eliminación, terminaré con "Med1" y "Med2". Si solo se marca "Med1" para su eliminación, terminaré con "Med1" y "Med2" y un "Med2" adicional. Si ninguno de los dos está marcado para su eliminación, terminaré con dos de cada "Med1" y "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

He sido súper cuidadoso y he comprobado más de un millón de veces que se permite: _destroy flag a través de parámetros fuertes, pero aún no hay dados.

Cualquier ayuda apreciada, debe ser algo obvio que simplemente no puedo ver.

EDITAR

Cambiando esto ...

# 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

A esto...

# Never trust parameters from the scary internet, only allow the white list through. def patient_params params.require(:patient).permit! end

Parece funcionar correctamente, así que todavía estoy seguro de que es algo que tiene que ver con parámetros sólidos, pero estoy seguro de que este último es menos seguro y no es la mejor práctica.