Как я могу это решить? Повторно инициализировать рубин Класс
class Person
end
class Person < ActiveRecord::Base
end
TypeError: superclass mismatch for class Person.
Я хочу переинициализировать класс.
Как я могу это решить? Повторно инициализировать рубин Класс
class Person
end
class Person < ActiveRecord::Base
end
TypeError: superclass mismatch for class Person.
Я хочу переинициализировать класс.
Вы можете (сорт) сделать это.
# initial definition
class Person
end
# new definition
class OverridePerson < ActiveRecord::Base
end
Person = OverridePerson
OverridePerson
Сходства к тому, что вы хотите сделать:
Person
будет относиться к новому классуDifferences, что вы хочу сделать:
случаев использования может быть:
redefine Person
, duck-typing, чтобы обмануть библиотеку или приложение. ИМО это совершенно законно для целей тестирования, хотя ActiveRecord :: Base будет сложным для утиного типа. Я рекомендую использовать FockAR или RSpec mocks или заглушки в исходном классе
Вы хотите создать класс под названием Person
, но он уже определен. В этом случае я рекомендую пространство имен внутри модуля.
Ухм, ты тоже получил объяснение без объяснения, это странно ... – NicoSantangelo
Да ... Ах, кто бы это ни был, только один раз! Не стесняйтесь расширять мой ответ. – user1158559
Я также рекомендую изучать рубиновые версии 2.0, где вы можете обезглавить патч класса, но выберите, где вы делаете доступными обезьяны. – user1158559
Как только вы создали класс в рубине, вы не сможете изменить свой суперкласс, открыв его снова. Вот почему вы получаете ошибку TypeError: superclass mismatch for class Person.
.
Другие ответы предоставили альтернативы, но важно отметить, что ни один из них не изменяет существующий класс Person
, но на самом деле создает новый класс и переназначает старую константу Person новому классу в рамках ограничений, уже заявленных @ user1158559 в его ответе.
+1, хотя это не совсем ответ. Но я думаю, что это хорошо, как «голос разума». Изменение суперкласса - плохая идея. – Kelvin
Мне нравится думать, что это answerr в том смысле, что он разъясняет, что то, что OP хочет сделать, фактически невозможно. Другие ответы, в том числе и принятые, предоставляют альтернативы, которые не решают точной проблемы, но могут быть полезны в разных сценариях, хотя то, почему кто-то захочет это сделать, выходит за рамки моего понимания. В любом случае, спасибо за рассмотрение этого вопроса ответ, достойный upvote @Kelvin =) – Cezar
Просто убедитесь, что вы используете одну и ту же подпись класса каждый раз.
class Person < ActiveRecord::Base
def x
end
end
class Person < ActiveRecord::Base
def y
end
end
Еще лучше, если у вас есть автозагрузка, а «Лицо» - это модель, просто ссылку «Лицо», чтобы убедиться, что исходное определение автоматически загружено из 'app/models/person.rb'. Затем снова откройте определение класса без дополнительной ссылки на суперкласс. – user1158559
Кроме того, указание суперкласса каждый раз не очень суровое и ненужное, если вы можете гарантировать порядок загрузки. – user1158559
@ user1158559 если 'Person' - это модель рельсов, она будет загружена, когда вы ее используете. В противном случае просто «требуется» из кода, который ему нужен. – Kelvin
Это не может быть ответом вы искать, но его путь к undefine a class
или константу, так что вы можете переопределить его, но он потеряет все оригинальные методы:
Object.send(:remove_const, :Person)
Я думаю, что вы должен объяснить вашу проблему немного больше. Вы определяете класс оба раза? – NicoSantangelo
Да. Я хочу изменить класс, который я объявляю раньше. Возможно, существует некоторое решение с свободной памятью. Я думаю, что это может решить мою проблему с ActiveRecord http://stackoverflow.com/questions/17506860/bug-with-activerecords – iiylll
Allpodo, я ненавижу говорить об этом, но мой ответ (хотя и правильный) является грязным взломом и является крайне маловероятно, чтобы решить вашу проблему. Вы должны использовать более четкие имена классов и имена таблиц. ActiveRecord определяет соглашение, которое связывает ваше имя класса с именем вашей таблицы, которое вы можете переопределить, если хотите. Возможно, вам придется перезапустить каждый процесс сервера Rails после удаления этих таблиц и «перезагрузить!» В консоли rails. – user1158559