Validando exclusão

187 views
Skip to first unread message

jonathan

unread,
Nov 11, 2013, 6:18:21 PM11/11/13
to rail...@googlegroups.com
Boa noite pessoal, sempre acompanho os posts mas essa � minha primeira
d�vida.
Tenho um modelo Estado que 'tem v�rias' Cidades, a quest�o � : Ao tentar
excluir um estado eu gostaria de validar se existem cidades associadas �
esse estado.

Na verdade eu j� consegui fazer isso no modelo dessa forma:

before_destroy :validates_if_has_cities
def validates_if_has_cities
if self.cities.size > 0
errors.add(:base,"Este estado n�o pode ser exclu�do pois possui
cidades")
end
self.errors.blank?
end

mas achei essa alternativa muuuuito trabalhosa, o rails n�o tem algo
mais autom�tico? Ou preciso fazer esse tratamento em todo relacionamento
1..N .

Desde j� agrade�o !!!
Vlw!!!!

Luis Vasconcellos

unread,
Nov 11, 2013, 6:22:06 PM11/11/13
to rail...@googlegroups.com
Se o before_destroy retornar falso a exclusão é cancelada, também dá pra verificar isso nele. http://apidock.com/rails/ActiveRecord/Callbacks/before_destroy



Luis Vasconcellos
Web Developer at DTM



2013/11/11 jonathan <jonathan...@gmail.com>
Boa noite pessoal, sempre acompanho os posts mas essa é minha primeira dúvida.
Tenho um modelo Estado que 'tem várias' Cidades, a questão é : Ao tentar excluir um estado eu gostaria de validar se existem cidades associadas à esse estado.

Na verdade eu já consegui fazer isso no modelo dessa forma:


before_destroy :validates_if_has_cities
  def validates_if_has_cities
    if self.cities.size > 0
      errors.add(:base,"Este estado não pode ser excluído pois possui cidades")
    end
    self.errors.blank?
  end

mas achei essa alternativa muuuuito trabalhosa, o rails não tem algo mais automático? Ou preciso fazer esse tratamento em todo relacionamento 1..N .

Desde já agradeço !!!
Vlw!!!!

--
--
Você recebeu essa mensagem porquê está inscrito no Google
Groups "rails-br".
Para enviar uma mensagem para o grupo, mande um email para rail...@googlegroups.com
Para se descadastrar, mande um e-mail para
rails-br+unsubscribe@googlegroups.com
Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7

--- Você está recebendo esta mensagem porque se inscreveu no grupo "rails-br" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para rails-br+unsubscribe@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.

Everaldo Gomes

unread,
Nov 11, 2013, 6:25:47 PM11/11/13
to rail...@googlegroups.com
Acho que você tem que usar has_many :cities, dependent: :restrict_with_error


4.3.2.4 :dependent

Controls what happens to the associated objects when their owner is destroyed:

:destroy causes all the associated objects to also be destroyed
:delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not execute)
:nullify causes the foreign keys to be set to NULL. Callbacks are not executed.
:restrict_with_exception causes an exception to be raised if there are any associated records
:restrict_with_error causes an error to be added to the owner if there are any associated objects
This option is ignored when you use the :through option on the association.


2013/11/11 Luis Vasconcellos <vasconc...@gmail.com>

Visite o grupo em http://groups.google.com/group/rails-br?hl=pt-BR
Leia nossa política de uso: http://goo.gl/YGgt7
 
---
Você está recebendo esta mensagem porque se inscreveu no grupo "rails-br" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para rails-br+u...@googlegroups.com.

jonathan

unread,
Nov 11, 2013, 6:40:46 PM11/11/13
to rail...@googlegroups.com
Muito bom Everaldo , eu havia testado o restrict, mas não quis usar por que ele lança um exception
Testei aqui com o :restrict_with_error mas não encontrei uma forma de colocar uma mensagem customizada.
Eu queria manter esse tratamento no modelo, então queria algo simples que adicionasse mensagens no 'errors' do modelo.
Se eu usar lançamento de exception acho q o melhor seria colocá-lo no controller, mas como disse antes, gostaria de fazer tudo no
model.
Bom, temos
* minha solução inicial ( que eu achei super trabalhosa)
* o restrict que lança uma exception que teoricamente seria tratado no controller ( eu gostaria de deixar tudo no modelo)
* o restrict_with_error (faz exatamente o que eu queria, o tratamento é no modelo e ele adiciona ao 'errors' do modelo, mas nao encontrei uma forma de customizar a mensagem)

Qual delas é a melhor ?

Sou novo no rails, e apesar de ter experiência com desenvolvimento, não quero ficar reinventando a roda. Quero aprender as melhores práticas em rails

Vlw pela disponibilidade pessoal.


2013/11/11 Luis Vasconcellos <vasconc...@gmail.com>


2013/11/11 jonathan <jonathan...@gmail.com>

Everaldo Gomes

unread,
Nov 11, 2013, 6:45:53 PM11/11/13
to rail...@googlegroups.com
Olá!

Talvez dê pra customizar com i18n. Fiz uma breve pesquisa e não achei nada...mas você que tá com a app rodando poderia ver mais fácil.

Sinceramente, não sei qual o melhor jeito...eu iria com o restrict, por default. Depende de suas regras de negócio...

Por exemplo, se tiver usando uma gem de autorização...ficaria bem diferente.



2013/11/11 jonathan <jonathan...@gmail.com>

Everaldo Gomes

unread,
Nov 11, 2013, 6:56:05 PM11/11/13
to rail...@googlegroups.com
Achei a mensagem: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/locale/en.yml#L19

activerecord.errors.messages.restrict_dependent_destroy.many


2013/11/11 Everaldo Gomes <everald...@gmail.com>

jonathan

unread,
Nov 11, 2013, 7:09:31 PM11/11/13
to rail...@googlegroups.com
Rá Everaldo realmente com a internacionalização funciona, testei aqui e deu pra mudar a mensagem... Vlw Obrigadão!!
Eu tava pensando em colocar aquela primeira opção toda trabalhosa que eu criei num módulo e fazer extensão. Talvez seja uma outra opção.
De qualquer forma vlw galera, pelo aprendizado !!

Everaldo Gomes

unread,
Nov 11, 2013, 7:11:05 PM11/11/13
to rail...@googlegroups.com
Legal.




2013/11/11 jonathan <jonathan...@gmail.com>

jonathan

unread,
Nov 12, 2013, 6:28:12 AM11/12/13
to rail...@googlegroups.com
Depois das dicas de ontem hoje eu fiz um modulozinho pra ajudar nessa validação, vejam como ficou:

module CustomValidationClassMethods

  def validates_restrict_destroy(filha,mens)
    # criando nome do metodo
    method_name = "validates_if_has_#{filha}"
    # adicionando o método à class
    define_method method_name.to_sym do
      if self.send(filha.to_s).size > 0
        self.errors.add(filha,mens)
      end
      return self.errors.blank?
    end
    # adicionando o método ao before_destroy
    before_destroy method_name.to_sym
  end
 
end

require './lib/modules/custom_validations.rb'
class State < ActiveRecord::Base
 
  has_many :cities
  extend CustomValidationClassMethods
  validates_restrict_destroy :cities,"Não é possível excluir esse Estado pois ele possui Cidades"

end

O que vcs acharam ?

Vlw !!

Everaldo Gomes

unread,
Nov 12, 2013, 6:42:11 AM11/12/13
to rail...@googlegroups.com
Com i18n ficaria mais fácil e limpo.

Você pode customizar a mensagem por model....


2013/11/12 jonathan <jonathan...@gmail.com>

jonathan

unread,
Nov 12, 2013, 8:31:47 AM11/12/13
to rail...@googlegroups.com
Everaldo, segui seu conselho e coloquei a mensagem no I18n

pt:
  activerecord:
    models:
      city:
        one: cidade
        other: cidades
      state:
        one: Estado
        other: Estados
    errors:
      messages:
        record_invalid: "Falha na Validação: %{errors}"
        restrict_dependent_destroy:
          one: "Não é possivel apagar esse %{model} pois ele possui um %{record} dependente"
          many: "Não é possivel apagar esse %{model} pois ele possui %{record} dependentes"

Funcionou 99%, o problema é que não to conseguindo traduzir o elemento %{record}, parece que ele ta encontrando
tradução somente para o elemento %{model}, olha a mensagem:
@messages={:base=>["Não é possivel apagar esse Estado pois ele possui cities dependentes"]}>

Everaldo Gomes

unread,
Nov 12, 2013, 9:14:27 AM11/12/13
to rail...@googlegroups.com
Pode ser o caso de abrir uma issue no projeto do Rails.




2013/11/12 jonathan <jonathan...@gmail.com>

Jonathan Vinicius

unread,
Jul 31, 2014, 12:36:01 PM7/31/14
to rail...@googlegroups.com
Estou passando pelo mesmo problema que o meu xará Jonathan.

Não consigo traduzir o record.

Vocês acharam alguma solução?
...

Bruno Porto

unread,
May 28, 2015, 4:57:59 PM5/28/15
to rail...@googlegroups.com
Sei que faz tempo que o tópico está aqui... mas CASO alguem procure na net e não encontre ou caia aqui... a solução é a seguinte:

Vamos supor que há dois models, um  sale e o outro product ... onde um sale pode ter muitos products
Se você colocou restrição tipo:

has_many
:products, dependent: :restrict_with_error


Ele vai tentar procurar o "products" dentro da classe "product" ... logo a tradução ficaria:

attributes:
  product
:
   
...
    products
: "produtos"


Estranho?! Mas ele faz assim kkkk
Imagino eu que devido a forma como ele está usando o "reflection" para buscar o nome do model do erro.
Reply all
Reply to author
Forward
0 new messages