Рефакторинг моделей ActiveRecord с базовым классом по сравнению с базовым модулем

Я использовал следующий при создании unittests для тестирования обновлений javaFX tableview

public class testingTableView {
        @BeforeClass
        public static void initToolkit() throws InterruptedException
        {
            final CountDownLatch latch = new CountDownLatch(1);
            SwingUtilities.invokeLater(() -> {
                new JFXPanel(); // initializes JavaFX environment
                latch.countDown();
            });

            if (!latch.await(5L, TimeUnit.SECONDS))
                throw new ExceptionInInitializerError();
        }

        @Test
        public void updateTableView() throws Exception {

            TableView<yourclassDefiningEntries> yourTable = new TableView<>();
            .... do your testing stuff

        }
    }

, хотя этот пост не связан с тестом, и это помогло мне заставить мой unittest работать

  • без initToolkit BeforeClass, тогда экземпляр TableView в unittest даст сообщение отсутствующего инструментария
13
задан Jo Liss 10 July 2012 в 13:59
поделиться

5 ответов

Существует фундаментальное различие между этими двумя методами, которое отсутствует во всех других ответах, и это реализация STI (наследование одной таблицы) rails:

http: //api.rubyonrails. org / classes / ActiveRecord / Base.html (Найдите раздел «Наследование одной таблицы»)

В основном, если вы реорганизуете свой базовый класс следующим образом:

class Base < ActiveRecord::Base
  def foo
    puts "foo"
  end
end

class A < Base
end

class B < Base
end

Тогда у вас должна быть таблица базы данных с именем «базы» со столбцом с именем «тип», который должен иметь значение «А» или «В». Столбцы в этой таблице будут одинаковыми для всех ваших моделей, и если у вас есть столбец, который принадлежит только одной из моделей, ваша «базовая» таблица будет денормализована.

Принимая во внимание, что если вы реорганизуете свой базовый класс, например this:

Module Base
  def foo
  puts "foo"
 end
end

class A < ActiveRecord::Base
 include Base
end

class B < ActiveRecord::Base
 include Base
end

Тогда не будет стола "

24
ответ дан 1 December 2019 в 19:31
поделиться

Оба эти метода будут работать. Когда я решаю использовать модуль или класс, у меня возникает вопрос, вписывается ли класс в иерархию объектов или это просто методы, которые я хочу использовать повторно. Если я просто пытаюсь исключить общий код по причинам СУХИМ, это звучит как модуль. Если действительно существует класс, который вписывается в иерархию, которая имеет смысл сама по себе, я использую класс.

Исходя из фона Java, это освежает, я могу принять эти решения.

5
ответ дан 1 December 2019 в 19:31
поделиться

У вас больше гибкости с модулем. Цель модуля - охватить разные типы классов. С помощью другого метода вы запираетесь в Базе. В остальном особой разницы нет.

Ответ Ruby на множественное наследование - примеси. Поскольку ваши классы уже наследуются от определенных классов Rails, они больше не могут наследовать от ваших пользовательских классов.

Итак, ваш выбор - объединить их в длинную цепочку или использовать миксин, который намного чище и проще для понимания.

4
ответ дан 1 December 2019 в 19:31
поделиться

Модуль дает вам большую гибкость в том, что 1) вы можете наследовать только от одного класса, но можете включать несколько модулей, и 2) вы не можете наследовать от базового класса, не наследуя его суперклассы, но вы можете включить модуль сам по себе (например, вы можете захотеть добавить метод «foo» к другому классу, который не является активной моделью записи).

Другое отличие состоит в том, что внутри методов в классе Base вы могли вызывать что-либо из ActiveRecord :: Base, но не могли делать это из модуля.

1
ответ дан 1 December 2019 в 19:31
поделиться

Это зависит от того, что вы действительно пытаетесь сделать.

  1. Переопределение или добавление методов в ActiveRecord :: Base : сделайте это, если вы хотите, чтобы каждая модель ActiveRecord в вашем приложении имела response_to foo .
  2. Подкласс ActiveRecord :: Base, и каждая модель наследуется от вашего подкласса : достигает того же уровня, что и 1, но каждая модель в вашем приложении должна расширять нетрадиционный класс , так зачем же беспокоиться.
  3. include module : Это отлично работает, если только некоторое количество моделей нуждается в доступе к foo . Это в значительной степени то, что делают все эти actions_as_ плагины.

В итоге, если вы хотите, чтобы каждая модель имела поведение, отличное от того, что уже предоставляет ActiveRecord :: Base, используйте вариант 1. Если только несколько ваших моделей требуют такого поведения, создать модуль и включить его в свои модели (вариант 3).

1
ответ дан 1 December 2019 в 19:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: