最近我遇到了类似的问题,谷歌把我带到了这里。我想要的是替换生成视图的默认 scss。最后我解决了它,所以我想为以后来这里的任何人分享解决方法。我的环境是 Ruby 2.3.0 和 Rails 5.0,我认为这至少也适用于 Rails 4+。
作为JGutierrezC的调试,.scss文件是由sass-rails gem而不是原来的railties gem生成的。如果你看一下 sass-rails 的代码,你会发现它只是在../template 下获取文件:
https://github.com/rails/sass-rails/blob/5-0-stable/lib/rails/generators/scss/assets/assets_generator.rb#L6
require "rails/generators/named_base"
module Scss
module Generators
class AssetsGenerator < ::Rails::Generators::NamedBase
source_root File.expand_path("../templates", __FILE__)
def copy_scss
template "stylesheet.scss", File.join('app/assets/stylesheets', class_path, "#{file_name}.scss")
end
end
end
end
所以如果你只在你的模板目录下放一个 .css 是行不通的,因为生成器总是在目录../template 中搜索模板文件,它不遵循中描述的转换导轨引导。好吧,我们需要做的是覆盖这种行为。让我们走进rails的主要生成器代码:
https://github.com/rails/rails/blob/5-0-stable/railties/lib/rails/generators.rb#L354
def self.lookup(namespaces) #:nodoc:
paths = namespaces_to_paths(namespaces)
paths.each do |raw_path|
["rails/generators", "generators"].each do |base|
path = "#{base}/#{raw_path}_generator"
begin
require path
return
rescue LoadError => e
raise unless e.message =~ /#{Regexp.escape(path)}$/
rescue Exception => e
warn "[WARNING] Could not load generator #{path.inspect}. Error: #{e.message}.\n#{e.backtrace.join("\n")}"
end
end
end
end
当您在分配path 之后插入一行以打印它的值并调用rails g scaffold ...,您可能会得到如下内容:
...
"rails/generators/rails/scss/scss_generator"
"generators/rails/scss/scss_generator"
"rails/generators/rails/scss_generator"
"generators/rails/scss_generator"
"rails/generators/scss/assets/assets_generator"
invoke scss
...
这行显示了rails的生成器查找过程。 being-resuce 块做了一件事——按照包含生成器的顺序找到第一个目录并要求它,然后返回。因此,如果我们在最后一个之前的目录中创建我们的生成器,它可能会被 rails 而不是原来的那个。只需将原始文件复制到您的应用程序工作区:
(your ruby install path)/ruby-2.3.0/gems/sass-rails-5.0.5/lib/rails/generators/scss/assets/*
到
(your app path)/lib/generators/rails/scss/
并将assets_generator.rb 重命名为scss_generator.rb。
然后再次运行scaffold命令,你会发现输出不一样了:
...
"rails/generators/rails/scss/scss_generator"
"generators/rails/scss/scss_generator"
invoke scss
...
Rails 找到了我们创建的生成器并需要它,太好了!现在 scss_generator 将使用模板 (your app path)/lib/generators/rails/scss/template/stylesheet.scss。所以最后要做的就是自定义它,更改将反映到脚手架的视图 scss。
如果你想替换默认的scaffold.scss,还有更多的事情要做。您需要将相关方法复制到 scss_generator.rb 中,因为您更改了原始查找路径,rails 不会在原始文件中重新使用它们。
require "rails/generators/named_base"
module Scss
module Generators
class AssetsGenerator < ::Rails::Generators::NamedBase
source_root File.expand_path("../templates", __FILE__)
def copy_scss
template "stylesheet.scss", File.join('app/assets/stylesheets', class_path, "#{file_name}.scss")
end
end
end
end
# ruby-2.3.0/gems/sass-rails-5.0.5/lib/rails/generators/scss/scaffold/scaffold_generator.rb
require "sass/css"
module Sass
module Generators
class ScaffoldBase < ::Rails::Generators::NamedBase
def copy_stylesheet
dir = "#{::Rails.application.config.root}/lib/templates/erb/scaffold/"
file = File.join(dir, "scaffold.css")
converted_contents = ::Sass::CSS.new(File.read(file)).render(syntax)
create_file "app/assets/stylesheets/scaffolds.#{syntax}", converted_contents
end
end
end
end
# ruby-2.3.0/gems/sass-rails-5.0.5/lib/rails/generators/scss/scaffold/scaffold_generator.rb
module Scss
module Generators
class ScaffoldGenerator < ::Sass::Generators::ScaffoldBase
def syntax() :scss end
end
end
end
并将copy_stylesheet方法中变量dir的值更改为你放置scaffold.scss的位置,如:
dir = "#{::Rails.application.config.root}/lib/templates/erb/scaffold/"。
现在你可以随意使用你自己的scaffold.css了!