Different Model type objects mapped from a single table

Asked

Viewed 214 times

1

It is possible to map from a single table of the database different objects of type Model with Activerecord in a Ruby on Rails project?

Suppose I have in the database a table with the name customers which will be populated by clients of the physical type and legal type (where the existence of the attribute CPF or CNPJ defines its type)

Tabela Clientes, a existência do atributo tipo CPF ou CNPJ define qual será minha classe Model

and needs the classes of the type Model of my application are more than one, being them Clientephysics and Legal clientele, using inheritance from a type class Person.

inserir a descrição da imagem aqui

Like the Activerecord can do this mapping? If not possible by it, there are other ways to do this?

And in this same context, when I need the CPF and CNPJ attributes of the class client are objects of the type Model in the application, what can I do?

I have this doubt because I would like to implement the validations of the CPF and CPNJ fields in their respective classes, leaving my project more cohesive, but not create more tables and relations in the database.

1 answer

0

The ActiveRecord supports yes this type of inheritance. For this to work first we have to add a type attribute para the model Pessoa. Creation of this table would be something like this:

rails g model Pessoa nome cpf cnpj type

All you need to do is create the two classes you inherit from Pessoa

# app/models/pessoa_fisica.rb
class PessoaFisica < Pessoa
end

and

# app/models/pessoa_juridica.rb
class Juridica < Pessoa
end

Ready, now all models access the same table. If you use the class Pessoa, the ActiveRecord will always return all the rows of this table, but if used PessoaFisica or PessoaJuridica it will only handle the records with the specified type. It is valid for both insertion and recovery.

The Validation can then be placed on each model separately, I suggest you extract this validation for a custom validator, outside the template file.

In the parish

 PessoaFisica.create(cpf: '111.222.333-44')
 => #<PessoaFisica id: 1, nome: nil, cpf: "111.222.333-44", cnpj: nil, type: "PessoaFisica", created_at: "2016-07-16 17:03:29", updated_at: "2016-07-16 17:03:29"> 

 PessoaJuridica.create(cnpj: '78.425.986/0036-15')
 => #<PessoaJuridica id: 2, nome: nil, cpf: nil, cnpj: "78.425.986/0036-15", type: "PessoaJuridica", created_at: "2016-07-16 17:04:13", updated_at: "2016-07-16 17:04:13"> 

 Pessoa.all
 => #<ActiveRecord::Relation [#<PessoaFisica id: 1, nome: nil, cpf: "111.222.333-44", cnpj: nil, type: "PessoaFisica", created_at: "2016-07-16 16:53:59", updated_at: "2016-07-16 16:53:59">, #<PessoaJuridica id: 2, nome: nil, cpf: nil, cnpj: "78.425.986/0036-15", type: "PessoaJuridica", created_at: "2016-07-16 17:04:13", updated_at: "2016-07-16 17:04:13">]> 


 PessoaFisica.all
 => #<ActiveRecord::Relation [#<PessoaFisica id: 1, nome: nil, cpf: "111.222.333-44", cnpj: nil, type: "PessoaFisica", created_at: "2016-07-16 16:53:59", updated_at: "2016-07-16 16:53:59">]> 


 PessoaJuridica.all
 => #<ActiveRecord::Relation [#<PessoaJuridica id: 2, nome: nil, cpf: nil, cnpj: "78.425.986/0036-15", type: "PessoaJuridica", created_at: "2016-07-16 17:04:13", updated_at: "2016-07-16 17:04:13">]> 
  • Thanks for your help, you removed my doubt about inheritance, but in case I need CPF or CNPJ attributes to be Model type classes, but keep them as table columns customers in the database? Exemplo.

  • @rafakx do not know what would motivate you to turn CPF and CNPJ into Models, but I believe that in most cases it would not be a good idea. What would be the reason?

  • In this case, to make my code more cohesive regarding validation methods. I do everything in their respective classes (class Cpf validates Cpf, class cnpj validates cnpj). But I intend to apply elsewhere, as in RG, here in Brazil exists the number and issuing body, in an internationalization the national registration document will no longer be the RG, then I prefer to relate by means of composition the Personal Physique class with another called National Document and in this, to have an inherited class called RG, ID, etc (If it is USA, it will be called ID...).

  • In this case I think you will have to use the same relationship scheme of natural and legal person... I don’t know any Rails compositing schemes. Or to get closer to composition, use relationships even if you can assign multiple documents to one person. I guess there’s no getting away from it.

Browser other questions tagged

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