1 Pirmasis kontaktas
Kai kuriate aplikaciją naudodami „rails“ komandą, iš tikrųjų naudojate „Rails“ generatorių. Tada galite gauti visų galimų generatorių sąrašą, paleisdami bin/rails generate
:
$ rails new myapp
$ cd myapp
$ bin/rails generate
PASTABA: Norėdami sukurti „Rails“ aplikaciją, naudojame globalią rails
komandą, kuri naudoja „gem install rails“ įdiegtą „Rails“ versiją. Kai esate aplikacijos kataloge, naudojame bin/rails
komandą, kuri naudoja aplikacijoje sujungtą „Rails“ versiją.
Gausite visų „Rails“ pateiktų generatorių sąrašą. Norėdami pamatyti išsamų tam tikro generatoriaus aprašymą, paleiskite generatorių su --help
pasirinkimu. Pavyzdžiui:
$ bin/rails generate scaffold --help
2 Kuriamas pirmasis generatorius
Generatoriai yra sukurti naudojant Thor, kuris suteikia galingas parinktis analizei ir puikią API failų manipuliavimui.
Sukurkime generatorių, kuris sukurs inicializavimo failą pavadinimu initializer.rb
viduje config/initializers
. Pirmas žingsnis yra sukurti failą lib/generators/initializer_generator.rb
su šiuo turiniu:
class InitializerGenerator < Rails::Generators::Base
def create_initializer_file
create_file "config/initializers/initializer.rb", <<~RUBY
# Čia pridėkite inicializavimo turinį
RUBY
end
end
Mūsų naujas generatorius yra gana paprastas: jis paveldi Rails::Generators::Base
ir turi vieną metodų apibrėžimą. Paleidus generatorių, kiekvienas viešas metodas generatoriuje vykdomas seka, kurioje jis yra apibrėžtas. Mūsų metodas iškviečia create_file
, kuris sukurs failą nurodytuose tiksluose su nurodytu turiniu.
Norėdami iškviesti naują generatorių, paleiskime:
$ bin/rails generate initializer
Prieš tęsiant, pažiūrėkime naujo generatoriaus aprašymą:
$ bin/rails generate initializer --help
„Rails“ paprastai gali gauti gerą aprašymą, jei generatorius yra sudėtinio pavadinimo, pvz., ActiveRecord::Generators::ModelGenerator
, bet ne šiuo atveju. Šią problemą galime išspręsti dviem būdais. Pirmasis būdas pridėti aprašymą yra iškvietus desc
viduje mūsų generatoriaus:
class InitializerGenerator < Rails::Generators::Base
desc "Šis generatorius sukuria inicializavimo failą config/initializers"
def create_initializer_file
create_file "config/initializers/initializer.rb", <<~RUBY
# Čia pridėkite inicializavimo turinį
RUBY
end
end
Dabar galime pamatyti naują aprašymą, paleidę --help
naujame generatoriuje.
Antrasis būdas pridėti aprašymą yra sukurti failą pavadinimu USAGE
tame pačiame kataloge, kuriame yra mūsų generatorius. Tai padarysime kitame žingsnyje.
3 Generatorių kūrimas su generatoriais
Patys generatoriai turi generatorių. Pašalinkime mūsų InitializerGenerator
ir naudokime bin/rails generate generator
, kad sukurtume naują:
$ rm lib/generators/initializer_generator.rb
$ 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
Tai yra tik sukurtas generatorius:
class InitializerGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
end
Pirma, pastebėkite, kad generatorius paveldi Rails::Generators::NamedBase
vietoj Rails::Generators::Base
. Tai reiškia, kad mūsų generatorius tikisi bent vieno argumento, kuris bus inicializatoriaus pavadinimas ir bus prieinamas mūsų kodo per name
.
Tai galime pamatyti, patikrinę naujo generatoriaus aprašymą:
$ bin/rails generate initializer --help
Usage:
bin/rails generate initializer NAME [options]
Taip pat pastebėkite, kad generatorius turi klasės metodą, vadinamą source_root
. Šis metodas nurodo mūsų šablonų vietą, jei tokių yra. Pagal numatytuosius nustatymus jis rodo į lib/generators/initializer/templates
katalogą, kuris buvo tik ką sukurtas.
Norėdami suprasti, kaip veikia generatorių šablonai, sukursime failą lib/generators/initializer/templates/initializer.rb
su šiuo turiniu:
# Čia pridėkite inicializavimo turinį
Ir pakeiskime generatorių, kad jis kopijuotų šį šabloną, kai jis yra iškviečiamas: ```ruby 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 ```
Dabar paleiskime mūsų generatorių:
$ bin/rails generate initializer core_extensions
create config/initializers/core_extensions.rb
$ cat config/initializers/core_extensions.rb
# Čia pridėkite inicializavimo turinį
Matome, kad copy_file
sukūrė config/initializers/core_extensions.rb
su mūsų šablono turiniu. (Kelio paskirties vietoje naudojamas file_name
metodas
paveldėtas iš Rails::Generators::NamedBase
.)
4 Generatoriaus komandų eilutės parinktys
Generatoriai gali palaikyti komandų eilutės parinktis naudodami class_option
.
Pavyzdžiui:
class InitializerGenerator < Rails::Generators::NamedBase
class_option :scope, type: :string, default: "app"
end
Dabar mūsų generatorių galima paleisti su --scope
parinktimi:
$ bin/rails generate initializer theme --scope dashboard
Parinkties reikšmės pasiekiamos generatoriaus metodams naudojant options
:
def copy_initializer_file
@scope = options["scope"]
end
5 Generatoriaus nustatymas
Išsprendžiant generatoriaus pavadinimą, „Rails“ ieško generatoriaus naudodamas kelis
failų pavadinimus. Pavyzdžiui, paleidus bin/rails generate initializer core_extensions
,
„Rails“ bando įkelti kiekvieną iš šių failų, kol vienas bus rastas:
rails/generators/initializer/initializer_generator.rb
generators/initializer/initializer_generator.rb
rails/generators/initializer_generator.rb
generators/initializer_generator.rb
Jei nei vienas iš šių failų nerandamas, bus iškelta klaida.
Mūsų generatorių įdėjome į aplikacijos lib/
katalogą, nes šis
katalogas yra $LOAD_PATH
, todėl leidžiama „Rails“ rasti ir įkelti failą.
6 „Rails“ generatorių šablonų perrašymas
„Rails“ taip pat ieško generatoriaus šablonų failų keliose vietose.
Viena iš šių vietų yra aplikacijos lib/templates/
katalogas.
Tai leidžia mums perrašyti „Rails“ įdiegtų generatorių naudojamus šablonus.
Pavyzdžiui, galime perrašyti [scaffold kontrolerio šabloną][] arba
[scaffold rodinio šablonus][].
Norėdami tai pamatyti veikiant, sukurkime lib/templates/erb/scaffold/index.html.erb.tt
failą su šiuo turiniu:
<%% @<%= plural_table_name %>.count %> <%= human_name.pluralize %>
Atkreipkite dėmesį, kad šablonas yra ERB šablonas, kuris atvaizduoja kitą ERB šabloną.
Taigi bet koks <%
, kuris turėtų pasirodyti rezultatuojamame šablone, turi būti pakeistas į <%%
generatoriaus šablone.
Dabar paleiskime „Rails“ įdiegtą scaffold generatorių:
$ bin/rails generate scaffold Post title:string
...
create app/views/posts/index.html.erb
...
app/views/posts/index.html.erb
turinys yra:
<% @posts.count %> Posts
7 „Rails“ generatorių perrašymas
„Rails“ įdiegtus generatorius galima konfigūruoti naudojant config.generators
,
įskaitant visišką kai kurių generatorių perrašymą.
Pirmiausia pažvelkime, kaip veikia scaffold generatorius.
$ bin/rails generate scaffold User name:string
invoke active_record
create db/migrate/20230518000000_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
create app/views/users/_user.html.erb
invoke resource_route
invoke test_unit
create test/controllers/users_controller_test.rb
create test/system/users_test.rb
invoke helper
create app/helpers/users_helper.rb
invoke test_unit
invoke jbuilder
create app/views/users/index.json.jbuilder
create app/views/users/show.json.jbuilder
Iš išvesties matome, kad scaffold generatorius iškviečia kitus
generatorius, pvz., scaffold_controller
generatorių. Ir kai kurie iš tų
generatorių taip pat iškviečia kitus generatorius. Ypač scaffold_controller
generatorius iškviečia keletą kitų generatorių, įskaitant helper
generatorių.
Perrašykime įdiegtą helper
generatorių nauju generatoriumi, kurį pavadinsime
my_helper
:
$ 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
Ir lib/generators/rails/my_helper/my_helper_generator.rb
faile apibrėšime
generatorių kaip:
class Rails::MyHelperGenerator < Rails::Generators::NamedBase
def create_helper_file
create_file "app/helpers/#{file_name}_helper.rb", <<~RUBY
module #{class_name}Helper
# Aš padedu!
end
RUBY
end
end
Galiausiai, mums reikia pasakyti „Rails“, kad naudotų my_helper
generatorių vietoje
įdiegto helper
generatoriaus. Tam naudojame config.generators
. config/application.rb
faile pridėkime:
config.generators do |g|
g.helper :my_helper
end
Dabar, jei paleisime scaffold generatorių dar kartą, matysime my_helper
generatorių
veikime:
$ bin/rails generate scaffold Article body:text
...
invoke scaffold_controller
...
invoke my_helper
create app/helpers/articles_helper.rb
...
PASTABA: Galbūt pastebėsite, kad įdiegto helper
generatoriaus išvestyje
yra "invoke test_unit", tuo tarpu my_helper
išvestyje to nėra.
Nors helper
generatorius pagal numatytuosius nesukuria testų, jis
suteikia galimybę tai padaryti naudojant hook_for
. Galime tai padaryti
įtraukdami hook_for :test_framework, as: :helper
į MyHelperGenerator
klasę.
Daugiau informacijos rasite hook_for
dokumentacijoje.
7.1 Generatorių atsarginės kopijos
Kitas būdas perrašyti konkretų generatorių yra naudojant atsargines kopijas.
Atsarginė kopija leidžia generatoriaus vardų erdvės deleguoti kitai generatorių vardų erdvei.
Pavyzdžiui, sakykime, norime perrašyti test_unit:model
generatorių savo my_test_unit:model
generatoriumi, tačiau nenorime pakeisti visų kitų test_unit:*
generatorių, pvz., test_unit:controller
.
Pirma, sukuriame my_test_unit:model
generatorių lib/generators/my_test_unit/model/model_generator.rb
:
module MyTestUnit
class ModelGenerator < Rails::Generators::NamedBase
source_root File.expand_path("templates", __dir__)
def do_different_stuff
say "Darome skirtingus dalykus..."
end
end
end
Toliau naudojame config.generators
, kad sukonfigūruotume test_framework
generatorių kaip my_test_unit
, tačiau taip pat sukonfigūruojame atsarginę galimybę, kad visi trūkstami my_test_unit:*
generatoriai būtų pakeičiami į test_unit:*
:
config.generators do |g|
g.test_framework :my_test_unit, fixture: false
g.fallbacks[:my_test_unit] = :test_unit
end
Dabar paleidus scaffold generatorių, matome, kad my_test_unit
pakeitė test_unit
, tačiau paveikti tik modelio testai:
$ bin/rails generate scaffold Comment body:text
invoke active_record
create db/migrate/20230518000000_create_comments.rb
create app/models/comment.rb
invoke my_test_unit
Darome skirtingus dalykus...
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
create app/views/comments/_comment.html.erb
invoke resource_route
invoke my_test_unit
create test/controllers/comments_controller_test.rb
create test/system/comments_test.rb
invoke helper
create app/helpers/comments_helper.rb
invoke my_test_unit
invoke jbuilder
create app/views/comments/index.json.jbuilder
create app/views/comments/show.json.jbuilder
8 Programos šablonai
Programos šablonai yra ypatingo tipo generatoriai. Jie gali naudoti visus generatorių pagalbos metodus, tačiau jie yra parašyti kaip Ruby skriptas, o ne kaip Ruby klasė. Štai pavyzdys:
# template.rb
if yes?("Ar norite įdiegti Devise?")
gem "devise"
devise_model = ask("Kaip norėtumėte pavadinti vartotojo modelį?", default: "User")
end
after_bundle do
if devise_model
generate "devise:install"
generate "devise", devise_model
rails_command "db:migrate"
end
git add: ".", commit: %(-m 'Pradinis commit')
end
Pirma, šablonas paklausia vartotojo, ar nori įdiegti Devise. Jei vartotojas atsako "taip" (arba "t"), šablonas prideda Devise į Gemfile
ir paklausia vartotojo, kaip nori pavadinti Devise vartotojo modelį (pagal nutylėjimą User
). Vėliau, po to, kai paleidžiamas bundle install
, šablonas paleidžia Devise generatorius ir rails db:migrate
, jei buvo nurodytas Devise modelis. Galiausiai, šablonas prideda ir užfiksuoja visą programos direktoriją naudojant git add
ir git commit
.
Šabloną galime paleisti, kuriant naują Rails aplikaciją, perduodant -m
parametrą rails new
komandai:
$ rails new my_cool_app -m path/to/template.rb
Alternatyviai, šabloną galime paleisti esamoje aplikacijoje naudojant bin/rails app:template
:
$ bin/rails app:template LOCATION=path/to/template.rb
Šablonai taip pat gali būti saugomi ne vietiniame diske - galite nurodyti URL vietoj kelio:
$ rails new my_cool_app -m http://example.com/template.rb
$ bin/rails app:template LOCATION=http://example.com/template.rb
9 Generatorių pagalbos metodai
Thor teikia daug generatorių pagalbos metodus per Thor::Actions
, tokius kaip:
Be to, Rails taip pat teikia daug pagalbos metodus per Rails::Generators::Actions
, tokius kaip:
Atsiliepimai
Jūs esate skatinami padėti pagerinti šio vadovo kokybę.
Prašome prisidėti, jei pastebite rašybos klaidų ar faktinių klaidų. Norėdami pradėti, galite perskaityti mūsų dokumentacijos prisidėjimo skyrių.
Taip pat gali būti nepilnos informacijos arba informacijos, kuri nėra atnaujinta. Prašome pridėti bet kokią trūkstamą dokumentaciją pagrindiniam. Patikrinkite Edge vadovus pirmiausia, ar problemas jau išspręsta arba ne pagrindinėje šakoje. Patikrinkite Ruby on Rails vadovų gaires dėl stiliaus ir konvencijų.
Jei dėl kokios nors priežasties pastebite kažką, ką reikia ištaisyti, bet negalite patys tai pataisyti, prašome pranešti apie problemą.
Ir galiausiai, bet ne mažiau svarbu, bet koks diskusijos dėl Ruby on Rails dokumentacijos yra labai laukiamos oficialiame Ruby on Rails forume.