Разрешение конфликта имен классов в приложении Rails - PullRequest
7 голосов
/ 17 сентября 2010

Я создавал приложение Rails, которое выполняет функции учета.В рамках этого у меня есть модель с именем класса Transaction.Пока все хорошо, я создавал эту функциональность в течение месяца или около того, и все работает как положено.

До сих пор ...

Я только что обнаружил некоторые старые функции отчетности, которыебыл разработан несколько месяцев назад с использованием библиотеки Ruport перестал работать.Похоже, что Ruport при создании PDF-файлов требует библиотеку, которая также имеет класс / модуль с именем Transaction.

TypeError in Admin/team reportsController#generate
Transaction is not a module

...

This error occurred while loading the following files:
  pdf/writer
  transaction/simple

Итак, я ищу быстрое решение здесь.Надеемся, что это не связано с переименованием моей Transaction модели и рефакторингом кода за последние несколько недель.

Ждем некоторых умных предложений:)

Ответы [ 3 ]

13 голосов
/ 17 ноября 2010

Уже ответили и старые, но я пришел сюда с той же проблемой, но решил ее по-другому.

У меня есть две модели с именами Pull и Query. Попытка ссылки на Query.some_static_method() в методе в Pull привела к разрешению запроса до ActiveRecord::AttributeMethods::Query:Module.

Решил, поместив перед ним пустое пространство имен с помощью ::Query.some_static_method()

7 голосов
/ 17 сентября 2010

Я полагаю, что проблема заключается в том, что Ruport требует гем PDF :: Writer, который, в свою очередь, требует гем Transaction :: Simple, который определяет модуль Transaction.

Конечно, в ActiveRecord есть метод #transaction, но я не думаю, что в Rails есть модуль или класс Transaction. Я буду счастлив, что меня исправят.

Пространство имен обычно является лучшей практикой для избежания конфликтов имен, подобных этому. Например.

module Account
  class Transaction < ActiveRecord::Base
    ....
  end
end 

Однако модели ActiveRecord с пространством имен могут вызывать другие проблемы.

Как бы много времени это ни занимало, лучше всего переименовать модель транзакции.

Вы все еще можете сохранить свою существующую таблицу базы данных транзакций, если хотите, поэтому ваши миграции не нужно менять, поместив self.table_name = "transactions" внутри вашей модели.

Ваши ассоциации с другими моделями также можно по-прежнему называть «транзакциями», указав имя класса в вашем вызове ассоциации. Э.Г.

class User < ActiveRecord::Base

  has_many :transactions, :class_name => "AccountTransaction"

end

Эти два предложения могут или не могут сэкономить вам время.

0 голосов
/ 17 сентября 2010

Ваша проблема может быть связана с тем, что Транзакция также является зарезервированным словом в Rails…

...