with rails has_many form_tag form example accepts_nested_attributes_for ruby-on-rails ruby-on-rails-4 nested-attributes

ruby-on-rails - form_tag - rails form has_many



<Parent''s Child> no puede estar en blanco mientras usa accept_nested_attributes_for(Rails 4) (2)

Tengo dos modelos: tengo un formulario anidado que permite a los usuarios ingresar atributos para @contact y @goal. Sin embargo, cuando voy a guardar la entrada del formulario, aparece el siguiente error:

1 error prohibited this contact from being saved: Goals contact can''t be blank

Aquí están mis objetivos y modelos de contacto, junto con el controlador de contacto:

class Contact < ActiveRecord::Base belongs_to :user has_many :goals accepts_nested_attributes_for :goals, allow_destroy: true validates_presence_of :user_id,:name,:title,:email end class Goal < ActiveRecord::Base belongs_to :contact validates_presence_of :title, :due_date, :contact_id end class ContactsController < ApplicationController before_action :set_contact, only: [:show, :edit, :update, :destroy] # GET /contacts # GET /contacts.json def index @contacts = current_user.contacts end # GET /contacts/1 # GET /contacts/1.json def show end # GET /contacts/new def new @contact = Contact.new 1.times { @contact.goals.build } end # GET /contacts/1/edit def edit end # POST /contacts # POST /contacts.json def create @contact = Contact.new(contact_params.merge(user_id: current_user.id)) respond_to do |format| if @contact.save format.html { redirect_to @contact, notice: ''Contact was successfully created.'' } format.json { render :show, status: :created, location: @contact } else format.html { render :new } format.json { render json: @contact.errors, status: :unprocessable_entity } end end end # PATCH/PUT /contacts/1 # PATCH/PUT /contacts/1.json def update respond_to do |format| if @contact.update(contact_params) format.html { redirect_to @contact, notice: ''Contact was successfully updated.'' } format.json { render :show, status: :ok, location: @contact } else format.html { render :edit } format.json { render json: @contact.errors, status: :unprocessable_entity } end end end # DELETE /contacts/1 # DELETE /contacts/1.json def destroy @contact.destroy respond_to do |format| format.html { redirect_to contacts_url } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_contact @contact = Contact.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def contact_params params.require(:contact).permit(:name, :title, :company, :email, :notes, goals_attributes: [:title, :due_date, :notes, :contact_id]) end end

Me aseguré de agregar objetivos_atributos a los parámetros de contacto (en el Controlador de contactos). ¿Alguna idea sobre cuál puede ser el problema? Aquí hay un enlace al proyecto: https://github.com/nowgeez/radiusapp

¡Gracias!


Encontré otra solución. Puede usar la opción inverse_of dentro de has_many y belongs_to :

class Contact < ActiveRecord::Base has_many :goals, inverse_of: :contact end class Goal < ActiveRecord::Base belongs_to :contact, inverse_of: :goals validates_presence_of :title, :due_date, :contact_id end

No sé exactamente por qué funciona, pero creo que es porque permite que contact_id se establezca correctamente, antes de la validación del objetivo.

Encontré la solución leyendo esta entrada de blog: http://homeonrails.com/2012/10/validating-nested-associations-in-rails/


La pista está en el error:

Goals contact can''t be blank

En tu modelo Goal , tienes la siguiente validación:

validates_presence_of :title, :due_date, :contact_id

Intente eliminar contact_id para probar si aceptará o no. Si acepta, significa que no está pasando el contact_id través de sus parámetros al modelo

Usamos los recursos heredados , que anexan automáticamente el parent_id (si usa su belongs_to ). Si está pasando los parámetros a través de accepts_nested_attributes_for , recomendaría simplemente eliminar la validación contact_id , ya que creo que se agregará como parte del proceso