Saving parent and child if both are valid in Rails

0

I have two classes Protocolo and Movimentacoes , in saving Protocolo I create a new Movimentação .

class Protocolo < ActiveRecord::Base
  has_many :movimentacoes
  after_create :movimentacao_inicial

  def movimentar(status, usuario, comentario = nil)
    usuario = Usuario.find(usuario) if usuario.is_a?(Integer)
    if movimentacoes.create(status: status, usuario: usuario, comentario: comentario).valid?
      update_columns(status_atual: status)
    else
      false
    end
  end

  def movimentacao_inicial
    movimentar('enviado', usuario)
  end

  validates_associated :movimentacoes
end

And class Move

class Movimentacao < ActiveRecord::Base
  belongs_to :protocolo
  validates :usuario, :protocolo, presence: true
end

So whenever Protocolo is saved, I should create a new Movimentação and update the current status of Protocolo with status of last movimentação created.

Problem: If Movimentacao is invalid, Protocolo has already been created and I can not create a movimentação before creating a protocolo .

Does anyone know of any way around this?

    
asked by anonymous 05.08.2016 / 21:17

1 answer

1

In my opinion the best thing you can do is to create a nested form using the fields of the move in the protocol view itself.

remove after_create from protocolo.rb

or use in ProtocoloController.rb

Protocolo.transaction do
  @protocolo.save
  @protocolo.movimentar
end

transaction rails

Another way to not use the transaction is to leave the controller the same way it is and make the @protocolo.save of the controller save movimentações.build

movimentação.rb

before_create :movimentacao_inicial

def movimentar(status, usuario, comentario = nil)
  usuario = Usuario.find(usuario) if usuario.is_a?(Integer)
  mov = movimentacoes.build(status: status, usuario: usuario, comentario: comentario)
  if mov.valid?
    self.status = status
    return true
  else
    self.errors.add(:base, 'error') # não tenho certeza se irá precisar, pois você não está chamando em um validate.
    return false
  end
end

@protocolo.save will check the validation of the class Move

    
10.08.2016 / 01:52