Saving father and son if both are valid in Rails

Asked

Viewed 33 times

0

I have two classes Protocolo and Movimentacoes, in the rescue of 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

E class Movement

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

So whenever Protocolo be saved, I must create a new Movimentação and update the current status of Protocolo with the status of the latter movimentação maid.

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

Does anyone know any way around this?

  • Did you manage to analyze the answer Luiz? Can I try to help you?

1 answer

1


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

remove after_create from protocolo.rb

or use on ProtocoloController.rb

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

transaction Rails


Another way not to use the transaction and leave the controller the way it is and do the @protocolo.save controller save the 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

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.