Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
656 views
in Technique[技术] by (71.8m points)

ruby on rails - How to have the scaffold to generate another partial view template file

I'm trying to customize my scaffold generator, and I would like to have a new partial for the view in the same directory, in particular _item to be called both inside index and show. I can get all the templates but I'm not able to generate this file through

rails g scaffold foo name:string

I tried to put _item.erb in /lib/templates/erb/scaffold/ (together with the other files) but it is ignored- Does anybody have a clue?

I use ruby on rails 3, but please let me know if the solution is valid for rails 2 as well. I also use simple_form (thus I already have the _form partial), but I think the solution should be valid even without it.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I came across this question hoping to find an answer as the default rails scaffold generator is pretty crippled if you want to:

  1. Refactor your scaffold views or make use of partials
  2. Use controller and view inheritance
  3. Support additional controller actions and their views
  4. Support a mix of template engines, erb, haml, slim, jbuilder, prawn etc

Alas, I rolled up my sleeves and figured out how to make rails scaffold generator support the above requirements which I make use of on my current project.

If you want full control over your scaffold templates when you type rails g scaffold Foo ... then read on!

The Problem

The default rails scaffold generator is template engine specific AND hard codes a fixed set of view files that it looks for.

The Solution

Use a custom generator and wire it up to the scaffold template generation.

I have included a generator below that looks in lib/templates/scaffold and will generate scaffold views for ALL files found there including templates, partials and sub-directories regardless of the template engine.

IMO this should be the default rails behaviour instead of us having to jump through hoops like this..

Implementation

Do the following:

  1. Put whatever templates or partials you want created when scaffolding into lib/templates/scaffold. Notice there is no erb subdirectory !!
  2. Configure the generator template engine for your project as shown below
  3. Add my custom view generator (included below)

Rails 4 generator configuration:

# config/initializers/generators.rb
Rails.application.config.generators do |g|
  # ...
  g.template_engine :all
  g.fallbacks[:all] = :erb # or haml/slim etc
end

Rails 3 generator configuration:

# config/application.rb
config.generators do |g|
  # ...
  g.template_engine :all
  g.fallbacks[:all] = :erb # or haml/slim etc
end

The custom scaffold generator:

# lib/generators/all/scaffold/scaffold_generator.rb
require 'rails/generators/named_base'
require 'rails/generators/resource_helpers'

module All # :nodoc:
  module Generators # :nodoc:
    class ScaffoldGenerator < Rails::Generators::NamedBase # :nodoc:
      include Rails::Generators::ResourceHelpers

      source_root File.join(Rails.root, 'lib', 'templates', 'scaffold', File::SEPARATOR)

      argument :attributes, type: :array, default: [], banner: "field:type field:type"

      def create_root_folder
        empty_directory File.join("app/views", controller_file_path)
      end

      def copy_view_files
        available_views.each do |view|
          template view, File.join("app/views", controller_file_path, view)
        end
      end

    protected
      def available_views
        # use all template files contained in source_root ie 'lib/templates/scaffold/**/*'
        base = self.class.source_root
        base_len = base.length
        Dir[File.join(base, '**', '*')].select { |f| File.file?(f) }.map{|f| f[base_len..-1]}
      end
    end
  end
end

Caveats

No warranty offered :)

I hope this helps others who want to refactor their scaffold views with partials and support multiple template engines.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...