Можно ли использовать вложенные атрибуты в сочетании с наследованием?
Вопрос
У меня есть следующие классы:
- Проект
- Человек
- Человек > Разработчик
- Человек > Менеджер
В Project
модель Я добавил следующие утверждения:
has_and_belongs_to_many :people
accepts_nested_attributes_for :people
И, конечно, соответствующие высказывания в классе Person
.Как я могу добавить Developer
к a Project
через nested_attributes
способ?Следующее не работает:
@p.people_attributes = [{:name => "Epic Beard Man", :type => "Developer"}]
@p.people
=> [#<Person id: nil, name: "Epic Beard Man", type: nil>]
Как вы можете видеть, type
атрибуты установлены на nil
вместо того , чтобы "Developer"
.
Решение
Я столкнулся с аналогичной проблемой несколько дней назад.Столбец наследования (т.е. type
) в модели STI является защищенным атрибутом.Выполните следующие действия, чтобы переопределить защиту по умолчанию в вашем Person
класс.
Рельсы 2.3
class Person < ActiveRecord::Base
private
def attributes_protected_by_default
super - [self.class.inheritance_column]
end
end
Рельсы 3
Обратитесь к решение предложенный @токланд.
Предостережение:
Вы переопределяете атрибут system protected.
Ссылка:
Другие советы
Решение для рельсов3: attributes_protected_by_default атрибуты , защищенные по умолчанию в настоящее время класс-метод:
class Person < ActiveRecord::Base
private
def self.attributes_protected_by_default
super - [inheritance_column]
end
end
Вышеприведенные исправления у меня не сработали, но это сработало (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(:тип=>'База').class == База
Для тех из нас, кто использует Mongoid, вам нужно будет создать _type
доступное поле:
class Person
include Mongoid::Document
attr_accessible :_type
end