Os atributos aninhados podem ser usados em combinação com a herança?
Pergunta
Eu tenho as seguintes aulas:
- Projeto
- Pessoa
- Pessoa > Desenvolvedor
- Pessoa > Gerente
No Project
Modelo Eu adicionei as seguintes declarações:
has_and_belongs_to_many :people
accepts_nested_attributes_for :people
E, claro, as declarações apropriadas na classe Person
. Como posso adicionar um Developer
para um Project
através de nested_attributes
método? O seguinte não funciona:
@p.people_attributes = [{:name => "Epic Beard Man", :type => "Developer"}]
@p.people
=> [#<Person id: nil, name: "Epic Beard Man", type: nil>]
Como você pode ver o type
atributos está definido como nil
ao invés de "Developer"
.
Solução
Eu encontrei um problema semelhante há alguns dias. A coluna de herança (ou seja type
) em um modelo STI é um atributo protegido. Faça o seguinte para substituir a proteção padrão em seu Person
classe.
Rails 2.3
class Person < ActiveRecord::Base
private
def attributes_protected_by_default
super - [self.class.inheritance_column]
end
end
Rails 3
Consulte o solução sugerido por @tokland.
Embargo:
Você está substituindo o atributo protegido pelo sistema.
Referência:
Outras dicas
Solução para Rails3: atributes_protected_by_default em agora um método de classe:
class Person < ActiveRecord::Base
private
def self.attributes_protected_by_default
super - [inheritance_column]
end
end
Patches acima não funcionaram para mim, mas isso aconteceu (Rails3):
class ActiveRecord::Reflection::AssociationReflection
def build_association(*options)
if options.first.is_a?(Hash) and options.first[:type].presence
options.first[:type].to_s.constantize.new(*options)
else
klass.new(*options)
end
end
end
Foo.bars.build (: type => 'baz'). Class == baz
Para aqueles de nós usando mongóides, você precisará fazer o _type
Acessível em campo:
class Person
include Mongoid::Document
attr_accessible :_type
end