Я только начинаю с моим первым веб-приложением Ruby on Rails. У меня есть куча разных моделей, представлений, контроллеров и так далее.
Я хочу найти хорошее место, чтобы придерживаться определений действительно глобальных констант, которые применяются ко всему моему приложению. В частности, они применяются как в логике моих моделей, так и в решениях, принимаемых по моим взглядам. Я не могу найти СУХОЕ место, чтобы поместить эти определения, где они доступны как для всех моих моделей, так и для всех моих представлений.
Чтобы взять конкретный пример, я хочу постоянную COLOURS = ['white', 'blue', 'black', 'red', 'green']
. Это используется повсеместно, и в моделях, и в представлениях. Где я могу определить его в одном месте, чтобы он был доступен?
Что я пробовал:
- Постоянные переменные класса в файле model.rb, с которыми они больше всего связаны, например
@@COLOURS = [...]
. Но я не мог найти вменяемый способ определить это так, чтобы я мог писать в своих взглядах,Card.COLOURS
а не что-то клёвоеCard.first.COLOURS
. - А метод на модели, что-то вроде
def colours ['white',...] end
- такая же проблема. - Метод в application_helper.rb - это то, что я делаю до сих пор, но помощники доступны только в представлениях, а не в моделях
- Я думаю, что я мог попробовать что-то в application.rb или environment.rb, но это не совсем верно (и они тоже не работают)
Нет ли способа определить что-либо доступное как из моделей, так и из представлений? Я имею в виду, я знаю, что модели и представления должны быть отдельными, но наверняка в некоторых доменах будут времена, когда им нужно ссылаться на одни и те же предметные знания?
источник
Ответы:
Если ваша модель действительно «отвечает» за константы, вы должны вставить их туда. Вы можете создавать методы класса для доступа к ним, не создавая новый экземпляр объекта:
Кроме того, вы можете создать переменные класса и метод доступа. Это, однако, не рекомендуется, поскольку переменные класса могут вызывать удивление при наследовании и в многопоточных средах.
Две вышеупомянутые опции позволяют вам изменять возвращаемый массив при каждом вызове метода доступа, если это необходимо. Если у вас действительно истинная неизменяемая константа, вы также можете определить ее в классе модели:
Вы также можете создать глобальные константы, которые доступны из любого места в инициализаторе, как в следующем примере. Это, вероятно, лучшее место, если ваши цвета действительно глобальны и используются в нескольких контекстах модели.
Примечание: когда мы определяем константы выше, часто мы хотим, чтобы
freeze
массив. Это препятствует тому, чтобы другой код позже (непреднамеренно) изменил массив, например, добавив новый элемент. Как только объект заморожен, он больше не может быть изменен.источник
config/initializers/my_constants.rb
маршруту, не забудьте перезапустить сервер:touch tmp/restart.txt
def self.colours
Пример не является идеальным. Каждый раз, когда вы вызываетеdef self.colours
, будет возвращен новый экземпляр массива .#freeze
не поможет в этом случае. Лучше всего объявлять ее как константу Ruby, и в этом случае вы всегда получите один и тот же объект.class Card; COLOURS = ['white', 'blue'].freeze; def self.colours; COLOURS; end; end
этом размещение массива на любом языке может быть потенциально проблематичным; с одной стороны, он использует память без (веской) причины. Если вы загружаете из БД и хотите кэшировать значение, можно также использовать переменную экземпляра класса, которая может быть лениво загружена с помощьюdef self.colours
метода. Договорились об аспекте неизменности, хотя.Некоторые варианты:
Используя константу:
Ленивый загружается с помощью переменной экземпляра класса:
Если это действительно глобальная константа ( хотя избегайте глобальных констант такого рода ), вы также можете рассмотреть возможность добавления константы верхнего уровня,
config/initializers/my_constants.rb
например.источник
extend
модуль в классе, так что он будет доступен сCard.COLOURS
.extend
его не работает для меня. При использованииinclude
я могу получить доступ как:Card::COLOURS
/models
. Намного лучше, если вы создадите инициализатор./models
, но только если он внутри модуля, например,module Constants; COLOURS = ...; end
в файле с именемmodels/constants.rb
.Начиная с Rails 4.2, вы можете использовать
config.x
свойство:Который будет доступен как:
Еще один способ загрузки пользовательских настроек:
В Rails 5 и 6 вы можете использовать
configuration
объект напрямую для пользовательской конфигурации, в дополнение кconfig.x
. Однако его можно использовать только для не вложенной конфигурации:Это будет доступно как:
источник
Rails.configuration.colours
всего (хотя я хотел бы, чтобы это было не так долго)config
, так же хорошо, какconfiguration
. Мы могли бы надеяться получить ярлык в какой-то момент :)ApplicationController
если между ними нет ничего другого. Если константа не имеет прямого отношения к контроллерам, я все равно рассмотрю глобальную конфигурацию и т. Д.Если константа нужна более чем в одном классе, я помещаю ее в config / initializers / contant.rb всегда во всех заглавных буквах (приведенный ниже список состояний усекается).
Они доступны через наше приложение, за исключением кода модели как такового:
Чтобы использовать константу в модели, используйте attr_accessor, чтобы сделать константу доступной.
источник
config/initializers/constants.rb
вероятно, будет лучшим выбором, хотяДля настроек всего приложения и глобальных констант я рекомендую использовать Settingslogic . Эти настройки хранятся в файле YML и доступны из моделей, представлений и контроллеров. Кроме того, вы можете создавать различные настройки для всех ваших сред:
Где-то в представлении (я предпочитаю вспомогательные методы для такого рода вещей) или в модели, вы можете получить, например, массив цветов
Settings.colors.split(/\s/)
. Это очень гибкий. И вам не нужно изобретать велосипед.источник
Используйте метод класса:
Затем
Model.colours
вернет этот массив. В качестве альтернативы, создайте инициализатор и оберните константы в модуле, чтобы избежать конфликтов пространства имен.источник
Попробуйте сохранить все константы в одном месте. В моем приложении я создал папку констант внутри инициализаторов следующим образом:
и я обычно сохраняю все константы в этих файлах.
В вашем случае вы можете создать файл в папке констант как
colors_constant.rb
colors_constant.rb
Не забыл перезапустить сервер
источник
Другой вариант, если вы хотите определить свои константы в одном месте:
Но все же сделайте их глобально видимыми, не имея к ним полного доступа:
источник
Распространенное место для размещения глобальных констант всего приложения - внутри
config/application
.источник
Обычно я использую модель / таблицу поиска в моей программе rails и использую ее для констант. Это очень полезно, если константы будут разными для разных сред. Кроме того, если у вас есть план по их расширению, скажем, вы хотите добавить «желтый» позднее, вы можете просто добавить новую строку в таблицу поиска и покончить с этим.
Если вы дадите администратору разрешения на изменение этой таблицы, они не придут к вам для обслуживания. :) СУХОЙ.
Вот как выглядит мой код миграции:
Я использую seed.rb, чтобы предварительно заполнить его.
источник
Глобальная переменная должна быть объявлена в
config/initializers
каталогеисточник
В зависимости от вашего состояния, вы также можете определить некоторые переменные окружения и получить их через
ENV['some-var']
код ruby, это решение может не подойти вам, но я надеюсь, что оно может помочь другим.Пример: вы можете создавать различные файлы
.development_env
,.production_env
,.test_env
и загрузить его в соответствии ваши среды приложений, проверить это генераторную dotenv-рельсы , которые автоматизируют это для вашего.источник