Создание и настройка генераторов и шаблонов Rails

Для Windows 15.05.2019
Для Windows

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

После прочтения этого руководства, вы узнаете:

  • Как посмотреть, какие генераторы доступны в вашем приложении.
  • Как создать генератор с использованием шаблонов.
  • Как Rails ищет генераторы, чтобы вызвать их.
  • Как Rails генерирует код Rails из шаблонов.
  • Как настроить скаффолд, создавая новые генераторы.
  • Как настроить скаффолд, изменяя шаблоны генератора.
  • Как использовать фолбэки, чтобы избежать переопределения большого набора генераторов.
  • Как создать шаблон приложения.

Первый контакт

При создании приложения с помощью команды rails фактически вы используете генератор Rails. После этого можно получить список всех доступных генераторов, просто вызвав rails generate:

$ rails new myapp $ cd myapp $ bin/rails generate

Вы получите список всех генераторов, поставляющихся с Rails. Если необходимо подробное описание, к примеру, генератора helper, можно просто сделать так:

Наш новый генератор очень прост: он наследуется от Rails::Generators::Base и содержит одно определение метода. Когда генератор вызывается, каждый публичный метод в генераторе выполняется в порядке, в котором он определен. Наконец, мы вызываем метод create_file , который создаст файл в указанном месте с заданным содержимым. Если вы знакомы с Rails Application Templates API, API генераторов покажется вам очень знакомым.

Чтобы вызвать наш новый генератор, нужно всего лишь выполнить:

$ bin/rails generate initializer

Перед тем, как продолжить, давайте посмотрим на описание нашего нового генератора:

$ bin/rails generate initializer --help

Rails обычно способен генерировать хорошие описания, если генератор расположен в пространствах имен, таких как ActiveRecord::Generators::ModelGenerator , но не в этом частном случае. Эту проблему можно решить двумя способами. Первым является вызов desc внутри нашего генератора:

Class InitializerGenerator < Rails::Generators::Base desc "This generator creates an initializer file at config/initializers" def create_initializer_file create_file "config/initializers/initializer.rb", "# Add initialization content here" end end

Теперь можно просмотреть новое описание, вызвав --help на новом генераторе. Вторым способом является добавление описания в файле USAGE в той же директории, что и наш генератор. Мы это сделаем на следующем этапе.

Создание генераторов с помощью генераторов

У самих генераторов есть генератор:

$ bin/rails generate generator initializer create lib/generators/initializer create lib/generators/initializer/initializer_generator.rb create lib/generators/initializer/USAGE create lib/generators/initializer/templates invoke test_unit create test/lib/generators/initializer_generator_test.rb

Вот только что созданный генератор:

Class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("templates", __dir__) end

Сперва обратите внимание, что он унаследован от Rails::Generators::NamedBase вместо Rails::Generators::Base . Это означает, что наш генератор ожидает как минимум один аргумент, который будет именем инициализатора и будет доступным в нашем коде в переменной name .

Это можно увидеть, если вызвать описание для генератора (не забудьте удалить файл старого генератора):

$ bin/rails generate initializer --help Usage: rails generate initializer NAME

Также можно увидеть, что в нашем новом генераторе есть метод класса source_root . Этот метод указывает на место расположения шаблонов нашего генератора, если таковые имеются, и по умолчанию он указывает на созданную директорию lib/generators/initializer/templates .

Чтобы понять, что такое шаблон генератора, давайте создадим файл lib/generators/initializer/templates/initializer.rb со следующим содержимым:

А теперь изменим генератор, чтобы он копировал этот файл при вызове:

Class InitializerGenerator < Rails::Generators::NamedBase source_root File.expand_path("templates", __dir__) def copy_initializer_file copy_file "initializer.rb", "config/initializers/#{file_name}.rb" end end

И выполним наш генератор:

$ bin/rails generate initializer core_extensions

Теперь мы видим, что инициализатор с именем core_extensions был создан в config/initializers/core_extensions.rb с содержимым нашего шаблона. Это означает, что copy_file копирует файл из корневой директории исходников в заданный путь назначения. Метод file_name автоматически создается, когда мы наследуем от Rails::Generators::NamedBase .

Доступные для генераторов методы раскрываются в этого руководства.

Поиск генераторов

При запуске rails generate initializer core_extensions Rails затребует эти файлы в следующем порядке, пока один из них не будет найден:

Rails/generators/initializer/initializer_generator.rb generators/initializer/initializer_generator.rb rails/generators/initializer_generator.rb generators/initializer_generator.rb

Если ни один не найден, вы получите сообщение об ошибке.

Вышеуказанный пример положит файлы в папку lib приложения, поскольку сказано, что эта директория принадлежит $LOAD_PATH .

Настройка рабочего процесса

Собственные генераторы Rails достаточно гибки, чтобы позволить вам настроить скаффолд. Они могут быть настроены в config/application.rb , вот несколько настроек по умолчанию:

Config.generators do |g| g.orm:active_record g.template_engine:erb g.test_framework:test_unit, fixture: true end

Так как мы настраиваем наш рабочий процесс, давайте сперва посмотрим, как выглядит наш скаффолд:

$ bin/rails generate scaffold User name:string invoke active_record create db/migrate/20130924151154_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources:users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder invoke test_unit create test/application_system_test_case.rb create test/system/users_test.rb invoke assets invoke coffee create app/assets/javascripts/users.coffee invoke scss create app/assets/stylesheets/users.scss invoke scss create app/assets/stylesheets/scaffolds.scss

Глядя на этот вывод, легко понять, как работают генераторы в Rails 3.0 и выше. Генератор скаффолда фактически не генерирует ничего, он просто вызывает другие. Это позволяет нам добавить/заменить/убрать любые из этих вызовов. Например, генератор скаффолда вызывает генератор scaffold_controller, который вызывает генераторы erb, test_unit и helper. Поскольку у каждого генератора одна функция, их просто использовать повторно, избегая дублирования кода.

Если хотите избежать генерации файла по умолчанию app/assets/stylesheets/scaffolds.scss при скаффолде нового ресурса, можно отключить scaffold_stylesheet:

Config.generators do |g| g.scaffold_stylesheet false end

Следующей настройкой рабочего процесса будет полное прекращение генерации таблиц стилей, JavaScript и фикстур для тестов скаффолда. Этого можно достичь, изменив конфигурацию следующим образом:

Если мы сгенерируем другой ресурс с помощью генератора скаффолда, мы увидим, что ни таблица стилей, ни JavaScript, ни фикстуры более не будут созданы. Если мы захотим настраивать его дальше, например использовать DataMapper и RSpec вместо Active Record и TestUnit, это достигается всего лишь добавлением соответствующих гемов в приложение и настройкой ваших генераторов.

Для демонстрации мы собираемся создать новый генератор хелперов, который просто добавляет несколько методов-ридеров для переменных экземпляра. Сначала мы создадим генератор в пространстве имен rails, так как тут rails ищет генераторы, используемые как хуки:

$ bin/rails generate generator rails/my_helper create lib/generators/rails/my_helper create lib/generators/rails/my_helper/my_helper_generator.rb create lib/generators/rails/my_helper/USAGE create lib/generators/rails/my_helper/templates invoke test_unit create test/lib/generators/rails/my_helper_generator_test.rb

Можно опробовать наш новый генератор, создав хелпер для продуктов:

$ bin/rails generate my_helper products create app/helpers/products_helper.rb

И следующий хелпер будет сгенерирован в app/helpers:

Module ProductsHelper attr_reader:products, :product end

Что, собственно, и ожидалось. Можно сообщить скаффолду использовать наш новый генератор хелпера, снова отредактировав config/application.rb:

Config.generators do |g| g.orm:active_record g.template_engine:erb g.test_framework:test_unit, fixture: false g.stylesheets false g.javascripts false g.helper:my_helper end

и увидев его в действии при вызове генератора:

$ bin/rails generate scaffold Article body:text [...] invoke my_helper create app/helpers/articles_helper.rb

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

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

Для этого мы изменим генератор следующим образом:

# lib/generators/rails/my_helper/my_helper_generator.rb class Rails::MyHelperGenerator < Rails::Generators::NamedBase def create_helper_file create_file "app/helpers/#{file_name}_helper.rb", <<-FILE module #{class_name}Helper attr_reader:#{plural_name}, :#{plural_name.singularize} end FILE end hook_for:test_framework end

Теперь, когда вызывается генератор хелпера, и как тестовый фреймворк настроен TestUnit, он попытается вызвать Rails::TestUnitGenerator и TestUnit::MyHelperGenerator . Поскольку ни один из них не определен, можно сообщить нашему генератору вместо них вызывать TestUnit::Generators::HelperGenerator , который определен, так как это генератор Rails. Для этого нужно всего лишь добавить:

# Search for:helper instead of:my_helper hook_for:test_framework, as: :helper

Теперь можно снова запустить скаффолд для другого ресурса и увидеть, что он также генерирует тесты!

Настройка рабочего процесса, изменяя шаблоны генераторов

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

В Rails 3.0 и выше генераторы не просто ищут шаблоны в корневом пути, они также ищут по другим путям. И одно из них - lib/templates . Поскольку мы хотим изменить Rails::Generators::HelperGenerator , можно это осуществить, просто сделав копию шаблона в lib/templates/rails/helper с именем helper.rb . Так давайте же создадим этот файл со следующим содержимым:

Module <%= class_name %>Helper attr_reader:<%= plural_name %>, :<%= plural_name.singularize %> end

и отменим последнее изменение в config/application.rb:

Config.generators do |g| g.orm:active_record g.template_engine:erb g.test_framework:test_unit, fixture: false g.stylesheets false g.javascripts false end

Если сгенерировать другой ресурс, то увидите абсолютно тот же результат! Это полезно, если хотите изменить шаблоны вашего скаффолда и/или макет, просто создав edit.html.erb , index.html.erb и так далее в lib/templates/erb/scaffold .

Шаблоны скаффолда в Rails часто используют теги ERB; эти теги необходимо экранировать, чтобы сгенерированный результат являлся валидным кодом ERB.

Например, в шаблоне необходим следующий экранированный тег ERB (обратите внимание на дополнительный %)...

<%%= stylesheet_include_tag:application %>

Чтобы сгенерировать следующий результат:

<%= stylesheet_include_tag:application %>

Добавление фолбэков генераторов

Еще одна особенность генераторов, которая очень полезна, это фолбэки. Например, представим, что вы хотите добавить особенность над TestUnit, такую как shoulda . Так как TestUnit уже реализует все генераторы, требуемые Rails, а shoulda всего лишь хочет переопределить часть из них, нет необходимости для shoulda переопределять некоторые генераторы, она может просто сообщить Rails использовать генератор TestUnit , если такой не найден в пространстве имен Shoulda .

Можно с легкостью смоделировать это поведение, снова изменив наш config/application.rb:

Config.generators do |g| g.orm:active_record g.template_engine:erb g.test_framework:shoulda, fixture: false g.stylesheets false g.javascripts false # Добавим фолбэк! g.fallbacks[:shoulda] = :test_unit end

Теперь, если создать скаффолд Comment, вы увидите, что были вызваны генераторы shoulda, но в итоге они всего лишь переуступили генераторам TestUnit:

$ bin/rails generate scaffold Comment body:text invoke active_record create db/migrate/20130924143118_create_comments.rb create app/models/comment.rb invoke shoulda create test/models/comment_test.rb create test/fixtures/comments.yml invoke resource_route route resources:comments invoke scaffold_controller create app/controllers/comments_controller.rb invoke erb create app/views/comments create app/views/comments/index.html.erb create app/views/comments/edit.html.erb create app/views/comments/show.html.erb create app/views/comments/new.html.erb create app/views/comments/_form.html.erb invoke my_helper create app/helpers/comments_helper.rb invoke shoulda create test/helpers/comments_helper_test.rb invoke jbuilder create app/views/comments/index.json.jbuilder create app/views/comments/show.json.jbuilder invoke test_unit create test/application_system_test_case.rb create test/system/comments_test.rb invoke assets invoke coffee create app/assets/javascripts/comments.coffee invoke scss

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

Шаблоны приложения

Gem "rspec-rails", group: "test" gem "cucumber-rails", group: "test" if yes?("Would you like to install Devise?") gem "devise" generate "devise:install" model_name = ask("What would you like the user model to be called? ") model_name = "user" if model_name.blank? generate "devise", model_name end

В вышеприведенном шаблоне мы определили, что приложение полагается на гемы rspec-rails и cucumber-rails , поэтому они будут добавлены в группу test в Gemfile . Затем мы зададим вопрос пользователю относительно того, хочет ли он установить Devise. Если пользователь ответит "y" или "yes" на этот вопрос, тогда шаблон добавит Devise в Gemfile вне какой-либо группы, а затем запустит генератор devise:install . Затем этот шаблон возьмет пользовательский ввод и запустит генератор devise с переданным ответом пользователя из последнего вопроса.

Представим, что этот шаблон был в файле template.rb . Можно его использовать, чтобы модифицировать результат команды rails new с помощью опции -m и передачей имени файла:

$ rails new thud -m template.rb

Эта команда сгенерирует приложение Thud , а затем применит шаблон к сгенерированному результату.

Шаблоны не обязательно должны храниться в локальной системе, опция -m также поддерживает онлайн шаблоны:

$ rails new thud -m https://gist.github.com/radar/722911/raw/

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

Добавление аргументов командной строки

Генераторы Rails легко модифицировать, чтобы они принимали произвольные аргументы командной строки. Эта функциональность исходит из Thor :

Class_option:scope, type: :string, default: "read_products"

Теперь наш генератор может быть вызван следующим образом.

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

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

Производство дешевой электроэнергии

Электрическая энергия нужна любому современному человеку. Ведь без многих бытовых устройств уже невозможно существовать, а все они практически работают от электричества. Желание сэкономить некоторых уже привело к приобретению ветряных генераторов, которые способны создавать ценный ресурс уже при воздушном движении в 8–9 м/сек. Причем такого генератора энергии из воздуха хватает на длительное время. Стоимость устройства отличается в зависимости от:

  • Накапливаемого объема электроэнергии
  • Материалов, из которых оно изготовлено
  • Способности реагировать на движения ветра
  • Есть умельцы, которые создают аналогичные генераторы из подручных материалов

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

Технологические особенности ветряного генератора

Ветряной генератор может в качестве основы иметь лопасти или барабанные цилиндры. Работает по принципу вертикальной или горизонтальной оси. Чаще всего используют ветряной генератор с горизонтальной осью. Основными элементами устройства являются:

  • Коробка передач
  • Вал ротора
  • Система торможения
  • Генератор, преображающий энергию в электрическую.

Дополнительно система может содержать мотор для получения энергии от лопастей при чрезвычайных обстоятельствах. Коробка передач позволяет контролировать вращение в зависимости от потока и плотности ветра, а также основных потребностей. Если генератор имеет лопасти, то делают их из прочного металлического сплава. Это позволяет не деформироваться элементам конструкции из-за факторов внешней среды.

Работает такое устройство достаточно просто. Когда ветер поворачивает лопасти или половинки барабана, вращается вал. Он соединяется с генератором, который по законам физики превращает кинетическую энергию в электрическую. Та, в свою очередь, передается или непосредственно на объект или накапливается специальным оборудованием, чтобы отдать энергию в нужный момент.

Как сделать ветряной генератор самостоятельно

Если есть желание попробовать сделать генератор своими руками, то лучше выбрать тот, что основан на барабане. Лопасти создаются из фанеры или железа, используемого при строительстве крыш. Подойдет также пластик. Толщина не должна быть слишком большой. Ротор подобрать максимально легкий, т. к. это будет уменьшать трение в подшипниках. Это будет способствовать тому, чтобы барабан легко мог раскручиваться под воздействием ветра. Подобная конструкция спокойно справиться с обслуживанием нужд небольшой дачи.

В случае создания лопастей из кровельного железа, его нужно хорошо обработать. Края же лопастей требуют дополнительного утяжеления. Обычно прикрепляют к лопастям металлические прутья. Диаметр прутьев подобрать в 5–6 мм.

Лопасти из фанеры покрываются олифой. Это защитит ее от разрушений. Толщина фанеры должна быть не менее 5 мм.

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

Элементы барабана следует тщательно промазывать места стыков. Делать это лучше масляной краской.

В качестве оси вертушки подойдет любая стальная труба. Нужно обратить внимание на параметры. Диаметр трубы должен составлять 30 мм и выше, а длина быть не менее двух метров.

Соединяющие лопасти крестовины лучше заказать сварщикам. Их делают из стальных полосок размером 5 на 60 мм. Можно использовать древесину, но такой вариант менее долговечен и надежен.

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

Ювелирная работа требуется при проведении подгонки трубы к подшипникам.

Нужно замерять расстояние между лопастями и осью. Оно должно быть:

  • Одинаковым
  • Не менее 140 мм

После этого уже создается основание, на котором устанавливаются шариковые подшипники. В качестве подставки может подойти:

  • Металлический угол
  • Металлическая пластина
  • Старая шестеренка

Основание должно быть подвергнуто сверлению. Число отверстий рассчитывается как два на лопасть. Лопасти крепятся с помощью специальных болтов.

Созданный таким образом генератор позволяет создать передаваемую мощность примерно 800 Вт, если скорость ветра достигает в среднем 9–11 м/с.

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

Производство или перепродажа

Если создание генератора своими руками кажется затруднительным, можно заняться тем, чтобы найти выгодных поставщиков. Например, китайские производители ветряных генераторов могут стать надежными партнерами. Останется лишь сформировать коммерческое предложение и подвести под него активную маркетинговую политику.

Можно также привлечь другого мастера для создания генераторов. В случае выбора посреднической схемы есть свои недостатки:

  1. Высокая степень риска, что конкуренты выйдут на такого же поставщика или специалиста.
  2. Вознаграждение за посредничество обычно меньше, чем надбавка за созданный продукт.
  3. Эмоциональные затраты на работу с посредниками выше. Могут срываться сроки, качество не соответствовать ожиданиям и так далее.

Если человек сам создает ветряные генераторы, то он и ценовую политику регулирует так, как ему удобно. Безусловно, что все затраты на материалы должны быть включены в стоимость продукта.

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

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

Следует также заранее продумать, что будет происходить с бизнесом, если заказов будет много. Скорее всего, понадобится площадка, на которой будет происходить сборка генераторов. Найм персонала придется официально оформлять, что увеличит издержки. Это классическая проблема роста должна решаться путем сокращения предельных затрат на покупаемые материалы.

Ведь чем больше заказов, тем и объемы приобретаемых материалов больше, поэтому у поставщиков можно просить скидки или бонусы. Это позволит удержать цену на ветряные генераторы на прежнем уровне.


Часто в состав первичного или уникального ключа входят цифровые поля, значения которых должны быть уникальны, то есть не повторяться ни в какой другой записи таблицы. В одних случаях такое значение является семантически значимым и формируется пользователем по определенному алгоритму -например, номер лицевого счета в банке. В других случаях лучше предоставить выработку такого значения приложению или серверу БД.

Для локальных СУБД (например, Paradox) для названной цели применяются автоинкрементные поля. При добавлении новой записи BDE автоматически устанавливает значение автоинкрементного поля так, чтобы оно было уникальным и не совпадало со значением данного автоинкрементного поля в других записях таблицы - не только существующих, но и удаленных. Иными словами, ранее использовавшееся значение автоинкрементного поля, даже если оно освободилось в результате удаления записи, никогда не назначается вновь. Изменить значение автоинкрементного поля нельзя.

В InterBase отсутствует аппарат автоинкрементных столбцов. Вместо этого для установки уникальных значений столбцов можно использовать аппарат генераторов.

Генератором называется хранимый на сервере БД механизм, возвращающий уникальные значения, никогда не совпадающие со значениями, выданными данным генератором в прошлом. Для создания генератора используется оператор

CREATE GENERATORИмяГенератора;

Для генератора необходимо установить стартовое значение при помощи оператора

SETGENERATOR ИмяГенератора ТО СтартовоеЗначение;

При этом СтартовоеЗначение должно быть целочисленным. Для получения уникального значения к генератору можно обратиться с помощью функции

GEN_ID(ИмяГенератора, шаг);

Эта функция возвращает увеличенное на шаг предыдущее значение, выданное генератором (или увеличенное на шаг стартовое значение, если ранее обращений к генератору не было).

ЗАМЕЧАНИЕ. Не рекомендуется переустанавливать стартовое значение генератора или менять шаг при разных обращениях к GEN_ID. В противном случае генератор может выдать неуникальное значение и, как следствие, будет возбуждено исключение "Дублирование первичного или уникального ключа" при попытке запоминания новой записи в ТБД.

Пример: Пусть в БД определен генератор, возвращающий уникальное значение для столбца N_RASH в таблице RASHOD

CREATE GENERATOR RASHOD_N_RASH;

SET GENERATOR RASHOD_N_RASH TO 20;

Обращение к генератору непосредственно из оператора

INSERT INTO RASHOD (N_RASH, DAT_RASH, KOLVO, TOVAR, POKUP) VALUES (GEN_ID (RASHOD_N_RASH, 1) ,"10-JAN-1997",100, "Сахар", "Лира, TOO") .

Присваивание ключевому столбцу уникального значения может быть реализовано через триггер, вызываемый перед запоминанием новой записи БД:



CREATE TRIGGER BI­­­­_RASHOD FOR RASHOD

NEW .N_RASH = GEN_ID (RASHOD_N_RASH, 1);

При этом в клиентском приложении, реализующем добавление новых записей в таблицу, столбец с уникальными значениями (в нашем случае N_RASH) в программе не заполняется и оператор INSERT имеет вид

INSERT INTO RASHOD (DAT_RASH, KOLVO, TOVAR, POKUP)

VALUES (: DAT_RASH, : KOLVO, : TOVAR, : POKUP)

Как можно заметить, столбец N_RASH в операторе не упоминается: все необходимые действия по заполнению этого столбца уникальным значением выполняет триггер BI_RASHOD.

"Обмануть" BDE можно, присваивая столбцу N_RASH любое значение, которое затем будет заменяться триггером на значение, полученное при помощи функции GEN_ID. Однако более корректным будет в данном случае использование не триггера, а процедуры:

CREATE PROCEDURE GET_N_RASH

RETURNS (NR INTEGER)

Электрический ток является основным видом энергии, совершающим полезную работу во всех сферах человеческой жизни. Он приводит в движение разные механизмы, дает свет, обогревает дома и оживляет целое множество устройств, которые обеспечивают наше комфортное существование на планете. Поистине, этот вид энергии универсален. Из нее можно получить все что угодно, и даже большие разрушения при неумелом использовании.

Но было время, когда электрические эффекты все так же присутствовали в природе, но никак не помогали человеку. Что же изменилось с тех пор? Люди стали изучать физические явления и придумали интересные машины - преобразователи, которые, в общем, и сделали революционный скачок нашей цивилизации, позволив человеку получать одну энергию из другой.

Так люди научились вырабатывать электричество из обычного металла, магнитов и механического движения - только и всего. Были построены генераторы, способные выдавать колоссальные по мощности потоки энергии, исчисляемые мегаваттами. Но интересно, что принцип действия этих машин не так уж сложен и вполне может быть понятен даже подростку. Что же такое Попробуем разобраться в этом вопросе.

Эффект электромагнитной индукции

Основой появления в проводнике электрического тока является электродвижущая сила - ЭДС. Она способна заставить перемещаться заряженные частицы, которых много в любом металле. Эта сила появляется только в случае, если проводник испытывает на себе изменение интенсивности магнитного поля. Сам эффект получил название электромагнитной индукции. ЭДС тем больше, чем больше скорость изменения потока магнитных волн. То есть, можно возле постоянного магнита перемещать проводник, или на неподвижный провод влиять полем электромагнита, меняя его силу, эффект будет один и тот же - в проводнике появится электрический ток.

Над этим вопросом в первой половине XIX века работали ученые Эрстед и Фарадей. Они же и открыли это физическое явление. В последствии на основе электромагнитной индукции были созданы генераторы тока и электродвигатели. Интересно, что эти машины легко могут быть преобразованы друг в друга.

Как работают генераторы постоянного и переменного тока

Понятно, что генератор электрического тока - это электромеханическая машина, вырабатывающая ток. Но на самом деле она есть преобразователь энергии: ветра, воды, тепла, чего угодно в ЭДС, которая уже вызывает ток в проводнике. Устройство любого генератора принципиально ничем не отличается от замкнутого проводящего контура, который вращается между полюсами магнита, как в первых опытах ученых. Только намного больше величина магнитного потока, создаваемого мощными постоянными или чаще электрическими магнитами. Замкнутый контур имеет вид многовитковой обмотки, которых в современном генераторе не одна, а минимум три. Все это сделано для того, чтобы получить как можно большую ЭДС.

Стандартный электрический генератор переменного тока (или постоянного) состоит из:

  • Корпуса . Выполняет функцию рамы, внутри которой крепят статор с полюсами электромагнита. В нем установлены подшипники качения роторного вала. Его изготавливают из металла, он также защищает всю внутреннюю начинку машины.
  • Статора с магнитными полюсами. На нем закреплена обмотка возбуждения магнитного потока. Его выполняют из ферромагнитной стали.
  • Ротора или якоря. Это подвижная часть генератора, вал которой приводит во вращательное движение посторонняя сила. На сердечнике якоря располагают обмотку самовозбуждения, где и образуется электрический ток.
  • Узла коммутации. Этот элемент конструкции служит для отведения электричества с подвижного вала ротора. Он включает в себя проводящие кольца, которые подвижно соединены с графитовыми токосъемными контактами.

Создание постоянного тока

В генераторе, продуцирующем постоянный ток, проводящий контур вращается в пространстве магнитной насыщенности. Причем за определенный момент вращения каждая половина контура оказывается вблизи того или иного полюсника. Заряд в проводнике за этот полуоборот движется в одном направлении.

Чтобы получить съем частиц, сделан механизм отвода энергии. Его особенность в том, что каждая половина обмотки (рамки) соединена с токопроводящим полукольцом. Полукольца между собой не замкнуты, а закреплены на диэлектрическом материале. За период, когда одна часть обмотки начинает проходить определенный полюс, полукольцо замыкается в электрическую схему щеточными контактными группами. Получается, на каждую клемму приходит только одного вида потенциал.

Правильнее назвать энергию не постоянной, а пульсирующей, с неизменной полярностью. Пульсация вызвана тем, что магнитный поток на проводник при вращении оказывает как максимальное, так и минимальное влияние. Чтобы эту пульсацию выровнять, применяют несколько обмоток на роторе и мощные конденсаторы на входе схемы. Для уменьшения потерь магнитного потока зазор между якорем и статором делают минимальным.

Схема генератора переменного тока

Когда происходит вращение подвижной части генерирующего ток устройства, в проводниках рамки также наводится ЭДС, как и в генераторе постоянного тока. Но небольшая особенность - генератор переменного тока устройство коллекторного узла имеет другое. В нем каждый вывод соединен со своим токопроводящим кольцом.

Принцип работы генератора переменного тока следующий: когда половина обмотки проходит возле одного полюса (другая, соответственно, возле противоположного полюса), в цепи движется ток в одном направлении от минимума к наивысшему своему значению и снова к нулю. Как только обмотки меняют свое положение относительно полюсов, ток начинает свое движение в обратном направлении с той же закономерностью.

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

газового типа

Конструкции генераторов тока, где вместо металлической рамки как носитель зарядов используют токопроводящую плазму, жидкость или газ, получили название МГД-генераторов. Вещества под давлением прогоняют в поле магнитной напряженности. Под воздействием все той же ЭДС индукции заряженные частицы обретают направленное движение, создавая электрический ток. Величина тока прямо пропорциональна скорости прохождения через магнитный поток, а также его мощности.

Генераторы МГД имеют более простое конструктивное решение - в них отсутствует механизм вращения ротора. Такие источники питания способны выдавать большие мощности энергии в короткие промежутки времени. Их применяют в качестве резервных устройств и в условиях экстренных аварийных ситуаций. Коэффициент, определяющий полезное действие (КПД) этих машин выше, чем имеет электрический генератор переменного тока.

Генератор синхронный переменного тока

Существуют такие типы генераторов переменного тока:

  • Машины синхронные.
  • Машины асинхронные.

Синхронный генератор переменного тока имеет строгую физическую зависимость между вращательным движением ротора и электричества. В таких системах ротор - это электромагнит, собранный из сердечников, полюсов и возбуждающих обмоток. Последние запитываются от источника постоянного тока посредством щеток и кольцевых контактов. Статор же представляет собой катушки провода, соединенные между собой по принципу звезды с общей точкой - нолем. В них уже наводится ЭДС и вырабатывается ток.

Вал ротора приводится в движение посторонней силой, обычно турбинами, частота движения которых синхронизирована и постоянна. Электрическая цепь, подключаемая к такому генератору, представляет собой трехфазную схему, частота тока в отдельной линии которой смещена на фазу в 120 градусов относительно других линий. Чтобы получить правильную синусоиду, направление магнитного потока в просвете между статорной и роторной частью регулируют конструкцией последних.

Возбуждение генератора переменного тока реализуют двумя методами:

  1. Контактным.
  2. Бесконтактным.

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

Бесконтактный принцип предусматривает, что синхронный генератор переменного тока на валу имеет дополнительные трехфазные обмотки, в которых при вращении наводится ЭДС и вырабатывается электричество. Оно через выпрямляющую схему поступает на катушки возбуждения ротора. Конструктивно в такой системе отсутствуют подвижные контакты, что упрощает систему, делая ее более надежной.

Асинхронный генератор

Существует асинхронный генератор переменного тока. Устройство его отличается от синхронного. В нем нет точной зависимости ЭДС от частоты с которой вал ротора вращается. Присутствует такое понятие как «скольжение S», которое характеризует эту разницу влияния. Величина скольжения определяется вычислением, так что неправильно думать, будто бы нет закономерности электромеханического процесса в асинхронном двигателе.

Если генератор, работающий вхолостую, нагрузить, то протекающий в обмотках ток будет создавать магнитный поток, препятствующий вращению ротора с заданной частотой. Так образуется скольжение, что, естественно, влияет на выработку ЭДС.

Современный асинхронный генератор переменного тока устройство подвижной части имеет в трех разных исполнениях:

  1. Полый ротор.
  2. Короткозамкнутый ротор.
  3. Фазный ротор.

Такие машины могут иметь само- и независимое возбуждение. Первая схема реализуется за счет включения в обмотку конденсаторов и полупроводниковых преобразователей. Возбуждение независимого типа создается дополнительным источником переменного тока.

Схемы включения генераторов

Все мощные источники питания линий электропередач вырабатывают трехфазный электрический ток. Они содержат в себе три обмотки, в которых образуются переменные токи со смещенной друг от друга фазой на 1/3 периода. Если рассматривать каждую отдельную обмотку такого источника питания, то получим однофазный переменный ток, идущий в линию. Напряжение в десятки тысяч вольт может вырабатывать генератор. потребитель получает с распределительного трансформатора.

Любой генератор переменного тока устройство обмоток имеет стандартное, но подключение к нагрузке бывает двух типов:

  • звездой;
  • треугольником.

Принцип работы генератора переменного тока, включенного звездой, предполагает объединение всех проводов (нулевых) в один, которые идут от нагрузки обратно к генератору. Это обусловлено тем, что сигнал (электрический ток) передается в основном через выходящий провод обмотки (линейный), который и называют фазой. На практике это очень удобно, ведь не нужно тянуть три дополнительных провода для подключения потребителя. Напряжение между линейными проводами и линейным и нулевым проводом будут отличаться.

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

Преимуществом трехфазного тока перед однофазным является его меньшая пульсация при выпрямлении. Это положительно сказывается на питаемых приборах, особенно двигателях постоянного напряжения. Также трехфазный ток создает вращающийся поток магнитного поля, который способен приводить в движение мощные асинхронные двигатели.

Где применимы генераторы постоянного и переменного тока

Генераторы постоянного тока значительно меньше по размерам и массе, чем машины переменного напряжения. Имея более сложное конструктивное исполнение чем последние, они все же нашли применение во многих отраслях промышленности.

Основное распространение они получили в качестве высокооборотных приводов в машинах, где требуется регулирование частоты вращения, например, в металлообрабатывающих механизмах, подъемниках шахт, прокатных станах. В транспорте такие генераторы установлены на тепловозах, различных судах. Множество моделей ветрогенераторов собраны на базе источников постоянного напряжения.

Генераторы постоянного тока специального назначения применяют в сварке, для возбуждения обмоток генераторов синхронного типа, в качестве усилителей постоянного тока, для питания гальванических и электролизных установок.

Назначение генератора переменного тока - вырабатывать электроэнергию в промышленных масштабах. Такой вид энергии подарил человечеству Никола Тесла. Почему именно изменяющий полярность ток, а не постоянный нашел широкое применение? Это связано с тем, что при передаче постоянного напряжения идут большие потери в проводах. И чем длиннее провод, тем потери выше. Переменное напряжение можно транспортировать на огромные расстояния при гораздо меньших затратах. Причем легко можно преобразовывать переменное напряжение (понижая и повышая его), который выработал генератор 220 В.

Заключение

Человек до конца не познал который пронизывает все вокруг. И электрическая энергия - это лишь малая часть открытых тайн мироздания. Машины, которые мы называем генераторами энергии, по сути очень просты, но то, что они могут нам дать, просто поражает воображение. Все же настоящее чудо здесь не в технике, а в мысли человека, которая смогла проникнуть в неисчерпаемый резервуар идей, разлитых в пространстве!

)
Источники: печатная документация и справочная информация по Borland InterBase, переписка листсервера esunix1.
последние изменения: 2 июля 1999.

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

Получение текущего значения генератора
Удаление генераторов

Создание генераторов
Генератор - это специальный объект базы данных, который генерирует уникальные последовательные числа. Эти числа могут быть использованы в качестве идентификаторов (например код клиента, номер счета и т.п.). Для создания генератора необходимо использовать оператор DDL

CREATE GENERATOR generatorname;

При выполнении такой команды происходит 2 действия:
1. На специальной странице БД отводится 4 байта для хранения значени генератора
2. В системной таблице RDB$GENERATORS заводится запись, куда помещаетс имя генератора иего номер (фактически смещение на странице генераторов).
После создания генератора его значения можно получать при помощи функции
GEN_ID(generatorname, inc_value)
где inc_value - число, на которое необходимо прирастить значение генератора.
Генераторы возвращают значения (и сохраняют свои значения на диске) вне контекста транзакции пользователя. Это означает, что если генератора было увеличено с 10 до 11 (инкремент 1), то даже при откате транзакции (ROLLBACK) значение генератора не вернется к предыдущему. Вместе с этим гарантируется что каждому пользователю будет возвращено уникальное значение генератора.
При выборке значения генератора запросом вида select gen_id(genname, x) from ... следует учитывать буферизацию выборки на клиенте. Т.е. в многопользовательской среде при выполнении двух таких запросов значения генератора будут увеличиваться "пачками", а не на величину x для каждой выбираемой записи.
Использование генераторов в триггерах и хранимых процедурах
Пример триггера, автоматически присваивающего уникальное значение ключевому полю таблицы:
создадим генератор для уникальной идентификации клиентов:

CREATE GENERATOR NEWCLIENT;

создадим триггер для таблицы CLIENTS:

CREATE TRIGGER TBI_CLIENTS FOR CLIENTS

ACTIVE BEFORE INSERT POSITION 0

BEGIN

В результате при создании новой записи полю CLIENT_ID будет автоматически присваиваться новое значение.
Однако при использовании генератора в триггере возникает проблема на клиентской стороне (например в BDE, используемом в Delphi, C++Builder ...), когда клиентское приложение пытается перечитать только-что вставленную запись. Поскольку триггер меняет значение первичного ключа вставляемой записи, BDE "теряет" такую запись и чаще всего выдает сообщение "Record/Key deleted". Поскольку SQL-сервер не может сообщить клиентскому приложению о новом значении ключевого поля, необходимо сначала запросить уникальное значение с сервера, и только затем использовать его во вставляемой записи. Сделать это можно при помощи хранимой процедуры

CREATE PROCEDURE GETNEWCLIENT

RETURNS (NID INTEGER )

BEGIN

NID = GEN_ID(NEWCLIENT, 1 ) ;

В Delphi, вы можете поместить компонент TStoredProc на форму, подсоединить его к данной процедуре, и например в методе таблицы BeforePost написать следующее

begin

begin

StoredProc1.ExecProc ;

StoredProc1.Params [ 0 ] .asInteger ;

end ;

end ;

После этого вышеприведенный триггер TBI_CLIENTS можно либо удалить, либо переписать так, чтобы генератор использовался только когда поле первичного ключа случайно приобрело значение NULL (например когда к таблице CLIENTS доступ осуществляется не через ваше приложение):

ALTER TRIGGER TBI_CLIENTS

BEGIN

IF (NEW .CLIENT_ID IS NULL) THEN

NEW .CLIENT_ID = GEN_ID(NEWCLIENT, 1 ) ;

Однако использование хранимой процедуры не всегда удобно - BDE может решить, что процедура вероятно изменяет какие-то данные на сервере, и в режиме autocommit завершит текущую транзакцию, что вызовет перечитывание данных TTable и TQuery. Более простым способом является получение значения генератора при помощи запроса:
SELECT GEN_ID(NEWCLIENT, 1) FROM RDB$DATABASE
При этом, если запрос помещен например в Query2, текст в BeforePost будет следующим:

begin

if DataSource.State = dsInsert then

begin

Query2.Open ;

ClientTable.FieldByName ("CLIENT_ID" ) .asInteger :=

Query2.Fields [ 0 ] .asInteger ;

Query2.Close ;

end ;

end ;

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

SET GENERATOR generatorname TO value;

Однако вы не сможете использовать такое выражение в теле триггера или хранимой процедуры, т.к. там можно использовать только операторы DML (а не DDL).
Если вы хотите обнулить генератор, или присвоить ему определенное значение в теле хранимой процедуры, то вы можете это сделать используя функцию GEN_ID:
(В данном примере генератор NEWCLIENT увеличивается на свое-же значение с отрицательным знаком.)
...
TEMPVAR = GEN_ID(NEWCLIENT, -GEN_ID(NEWCLIENT, 0);
...
Будьте внимательны при выполнении таких операций в многопользовательских средах. Приложения, процедуры и триггеры, которые в данный момент используют этот генератор, могут предполагать что он не будет "обнулен". Обязательно проверяйте "обнуление" генератора на возникновение конфликтных ситуаций при работе 2-х и более пользователей.
Получение текущего значения генераторов
Текущее значение генератора можно получить, вызвав функцию GEN_ID с нулевым увеличением значения генератора. Это можно сделать не только в триггере или хранимой процедуре, но и оператором SELECT

SELECT GEN_ID(NEWCLIENT, 0 ) FROM RDB$DA TABASE

Результатом выполнения запроса будет одна запись с одним полем, содержащим текущее значение генератора. Таблица RDB$DATABASES выбрана как содержаща в большинстве случаев одну запись, хотя использовать можно и любую другую таблицу.
При работе в многопользовательских средах будьте внимательны - в то время как вы получили "текущее" значение генератора, другое приложение может его изменить, и таким образом "текущее" значение окажется устаревшим. Тем более не рекомендуется использовать "текущее" значение генератора для его последующего изменения.
Удаление генераторов
В языке DDL Borland Interbase нет оператора для удаления генератора. Неизвестно, чем это вызвано, но серьезной проблемы не представляет. В самом начале статьи было упомянуто, что запись о генераторе создается в таблице RDB$GENERATORS. Эту запись, безусловно, можно удалить. Однако место, распределенное на странице генераторов, освобождено не будет. Оно будет освобождено только после того, как вы сделаете вашей БД BACKUP/RESTORE.
Нестандартное применение генераторов
Вы уже видели, что функцию GEN_ID можно использовать в операторе SELECT.
Вот как можно получить количество записей, выбранных запросом:

SET GENERATOR MYGEN TO 0 ;

SELECT GEN_ID(MYGEN, 1 ) , FIELD1, FIELD2, FIELD3, ... FROM MYTABLE.

Такой запрос вернет в качестве первого поля порядковый номер записи, и после выполнения запроса генератор MYGEN будет содержать количество возвращенных записей. Кроме этого, во время выполнения этого запроса любой другой пользователь этой-же БД может получить текущее значение генератора MYGEN и узнать сколько записей уже выбрано запросом на текущий момент (нечто вроде ProgressBar, однако число записей все-равно неизвестно до окончания выполнения запроса).
Функцию GEN_ID можно также использовать и как "выключатель" длительных запросов. Пример приведен для БД EMPLOYEE.GDB.

Фактически такой запрос означает - "выбирать записи пока значение генератора = 0". Как только другой пользователь или ваше приложение в другом коннекте выполнит операцию

SET GENERATOR EMP_NO_GEN TO 1 ;

запрос прекратится, т.к. условие WHERE станет равным FALSE.
(то-же самое, и даже в более сложных вариантах, можно делать при помощи UDF в Borland InterBase 4.2. см "Особенности версии 4.2")
примечание: обязательно учтитывайте буферизацию записей клиентской частью (gds32.dll) или сервером при выполнении подобных запросов. Например, приведенный выше запрос с проверкой генератора в where "выключится" не сразу, а через некоторое время.
Безусловно, в многопользовательской среде невозможно использовать в таких целях один и тот-же генератор. Для решения этой проблемы можно завести глобальный генератор, который будет выдавать уникальные идентификаторы пользователям при коннекте, а клиентское приложение будет запоминать его номер и хранить на локальном компьютере для последующего использования. Логика работы может быть следующая:
Клиентское приложение при запуске определяет, есть-ли для него (например в Registry или INI-файле) "именной" генератор.
Если нет, то оно операцией SELECT GEN_ID(GlobalGen, 1) FROM RDB$DATABASE получает идентификатор (например 150), создает на сервере собственный генератор операцией CREATE GENERATOR USER_N; (например USER150). После чего сохраняет имя этого генератора на локальном диске.
Если да, то приложение обнуляет "именной" генератор операцией SET GENERATOR ... TO 0; (в нашем примере SET GENERATOR USER150 TO 0;), и выдает запросы с использованием данного генератора.



Рекомендуем почитать

Наверх