Как мне искать конфликтующие классы в Rails? - PullRequest
1 голос
/ 02 декабря 2011

Я использую Rails 3.1 в проекте, и bundler добавил довольно много гемов, которые мне не очень хорошо известны.

По какой-то причине в режиме разработки (возможно, потому что он продолжает выгружать классы) я периодически сталкиваюсь с ActiveRecord :: AssociationTypeMismatch. Вот как это выглядит:

Character(#31360520) expected, got Character(#23815500)

Я считаю, что один из драгоценных камней определил класс «Персонаж», и это противоречит моей модели «Персонаж» ActiveRecord. У меня возникают проблемы с поиском источника этой проблемы, поскольку он приводит к множеству общих результатов, и я не уверен, как эти числа называются сообществом Ruby (идентификатор класса?).

Итак, несколько вопросов, с которыми я бы хотел помочь:

  1. что это за число в скобках после имени класса?
  2. Как я могу посмотреть, откуда этот класс (из какого драгоценного камня), основываясь на идентификаторе, указанном в исключении?
  3. Какова лучшая практика здесь для обычно называемых моделей ActiveRecord? Должен ли я указывать пространство между моими моделями или в этом больше виноват автор драгоценного камня?

1 Ответ

0 голосов
/ 02 декабря 2011

Я своего рода нуб, поэтому не считайте все, что я говорю, установленной истиной - но я думаю, что могу помочь.

вопрос 1

Не уверен, но я подозреваю, что эти цифры object_id с ожидаемого класса. В ruby ​​классы тоже являются объектами (хотя и одиночными объектами), поэтому они имеют object_id, как и любой другой объект (вы можете вызвать object_id для любого объекта, чтобы получить его уникальный идентификатор). Если вы хотите получить хэш каждого класса, загруженного в вашу среду вместе с их идентификатором, вы можете попробовать что-то вроде этого в консоли:

    all_classes = ObjectSpace.each_object.select {|o| o.class == Class}
    with_ids    = Hash[ all_classes.map {|c| [c,c.object_id] } ]

вопрос 2

В консоли все классы отображаются с указанием полного пути к пространству имён, поэтому с помощью приведенного выше сценария вы сможете различить два ваших Character класса, если они принадлежат другому пространству имён. Однако, если пространство имен идентично, проблема может стать проблемной, потому что одно из вашего определения класса будет переопределять другое, в зависимости от порядка загрузки. Я не удивлюсь, если использование ri в вашей оболочке поможет вам найти драгоценный камень преступника в этом случае.

вопрос 3

Я бы сказал: избегайте расплывчатых, слишком распространенных названий для ваших моделей; но в этом случае я бы сказал, что драгоценный камень виноват, потому что тот, кто предоставляет драгоценный камень, должен быть очень осторожен, чтобы не загрязнять пространство имен, особенно если оно загрязняет пространство имен ActiveRecord::Base.

...