Вкратце, я хочу, например, переопределить и/или добавить дополнительные файлы при запуске rails generate scaffold MyModel name:string
.
destroy.turbo_stream.haml
, _mymodel.html.haml
Я провел день, читая документацию, читая, как переопределять шаблоны с помощью генераторов рельсов, на https://guides.rubyonrails.org/generators.html#overriding-rails-generator-templates вместе с множеством сообщений о том, как это сделать. переопределить различные части контроллеров.
Хотя мне удалось переопределить некоторые представления, мне все же удалось найти магический путь, позволяющий переопределить controller.rb
, используемый во время генерации скаффолда.
Для этого я должен добавить файл контроллера где-нибудь в lib/templates
, но ничего не работает.
Я хотел добавить before_action :authenticate_user!
и некоторые другие изменения, которые я хочу, чтобы они всегда присутствовали в каркасных контроллерах.
Любые мысли относительно конкретного местоположения в рельсах... в документации это так: https://github.com/rails/rails/blob/main/railties/lib/rails/generators/rails/scaffold_controller/templates/ контроллер.rb.tt
Но тогда куда, lib/
, это девается?
lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
lib/templates/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
lib/templates/controller.rb.tt
Мне бы хотелось немного помощи. ПОМОЩЬ!! :)
P.S. И если вы знаете, как добавить дополнительные представления (например, destroy.turbo_stream.haml
к сочетаниям представлений вместе с _MODEL.html.haml
, я бы тоже хотел это выяснить.
Переопределить представления
https://github.com/haml/haml-rails/tree/master/lib/generators/haml/scaffold/templates
# lib/generators/haml/scaffold/templates/show.html.haml
# .--' | |
# | .--' .------------'
# v v v
lib/templates/haml/scaffold/show.html.haml
$ bin/rails g scaffold Testing
...
$ cat app/views/testings/show.html.haml
hi haml
Переопределить файл контроллера.rb
Переопределить шаблон контроллера по умолчанию из драгоценного камня Railties:
# lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt
# .--------' | |
# | .--------' .------------------'
# v v v
lib/templates/rails/scaffold_controller/controller.rb.tt
Добавляйте к просмотрам такие как
destroy.turbo_stream.haml
.
Создайте генератор в пространстве имен рельсов:
$ bin/rails g generator rails/my_scaffold
# lib/generators/rails/my_scaffold/my_scaffold_generator.rb
class Rails::MyScaffoldGenerator < Rails::Generators::NamedBase
# run default scaffold
invoke "scaffold_controller"
# add new stuff
include Rails::Generators::ResourceHelpers
source_root File.expand_path("templates", __dir__)
def copy_view_files
["destroy.turbo_stream.haml"].each do |filename|
template filename, File.join("app/views", controller_file_path, filename)
end
end
end
# lib/generators/rails/my_scaffold/templates/destroy.turbo_stream.haml.tt
# TODO: make a template
Измените генератор контроллера лесов по умолчанию:
# config/application.rb
config.generators do |g|
g.scaffold_controller :my_scaffold
end
$ bin/rails g scaffold Testing
...
create app/views/testings/destroy.turbo_stream.haml
Если хотите, вы можете получить немного более детализированную информацию:
# config/application.rb
config.generators do |g|
g.template_engine :my_scaffold
end
а затем вместо того, чтобы вызывать весь эшафот, просто invoke "haml:scaffold"
все остальное остается прежним.
Это не самый красивый способ добавления в scaffold, поскольку журнал scaffold вложен в my_scaffold. Если вы хотите добавить этот генератор, который будет вызываться скаффолдом, вам придется добавить новый хук:
https://api.rubyonrails.org/classes/Rails/Generators/Base.html#method-c-hook_for
Например, посмотрите, как это делает jbuilder:
https://github.com/rails/jbuilder/blob/v2.11.5/lib/jbuilder/railtie.rb#L29
https://github.com/rails/jbuilder/tree/v2.11.5/lib/generators/rails
очень ценю это! Это действительно помогло мне решить больное место. Я обнаружил, что не могу переопределить haml-rails
, поэтому я, скорее всего, просто перезапишу их полностью или перегружу генератор :haml
для своих целей. Тем не менее, я думаю, что меня разблокировали. Дайте мне знать, если у вас есть баночка с наконечниками. ;)
@WardW.Vuillemot, вы имеете в виду переопределить шаблоны представлений? должно быть lib/templates/haml/scaffold/show.html.haml
и т. д. github.com/haml/haml-rails/tree/master/lib/generators/haml/…
Ради того, чтобы добавить больше текстуры к ответу Алекса, который на 100% ответил на мои вопросы.
Я хотел добавить частичное представление, такое как app/views/my_models/_my_model.html
, которое заполнено атрибутами и значениями модели.
По умолчанию приведенный выше пример от Алекса оказался неэффективным, пока я не наткнулся на https://garrettdimon.com/journal/posts/creating-custom-rails-generators, подробности см. на рис. 13.
Это привело к некоторым незначительным изменениям или:
# lib/generators/rails/my_scaffold/my_scaffold_generator.rb
class Rails::MyScaffoldGenerator < Rails::Generators::NamedBase
# run default scaffold
invoke 'scaffold_controller'
argument :attributes, type: :array, default: [],
banner: "field[:type][:index] field[:type][:index]"
# add new stuff
include Rails::Generators::ResourceHelpers
source_root File.expand_path('templates', __dir__)
def copy_view_files
['destroy.turbo_stream.haml'].each do |filename|
template filename, File.join('app/views', controller_file_path, filename)
end
['partial.html.haml'].each do |filename|
template filename, File.join('app/views', controller_file_path, "_#{singular_table_name}.html.haml")
end
end
end
Более конкретно, я добавил две вещи:
argument :attributes, type: :array, default: [],
banner: "field[:type][:index] field[:type][:index]"
что гарантирует доступ к атрибутам модели в шаблоне.
['partial.html.haml'].each do |filename|
template filename, File.join('app/views', controller_file_path, "_#{singular_table_name}.html.haml")
end
добавляет частичный фрагмент и переименовывает его в единственное имя модели
А затем я добавил в свои шаблоны генератора:
# lib/generators/rails/my_scaffold/templates/partial.html.haml.tt
.container
<%- attributes.each do |attribute| -%>
%p
%b <%= attribute.name.humanize %>:
=<%= singular_table_name %>.<%= attribute.name %>
<%- end -%>
= link_to 'Edit', edit_<%= singular_table_name %>_path(<%= singular_table_name %>), class: 'btn btn-secondary m-1'
Обратите внимание: я не нашел .tt
совершенно необходимым, поскольку я использую haml
вместо erb
, поскольку tt
сам по себе является вариантом tt
, или я так понимаю.
И это, в сочетании с ответом Алекса выше, гарантирует
.tt
понадобится, если вы будете использовать команду directory
вместо всего «каждого шаблона»: directory ".", File.join("app/views", controller_file_path
Просто хотел признать это; Я сообщу, если у меня возникнут проблемы. Я ценю очень подробный ответ.