我正在尝试创建一个Rails应用程序模板,我在那里有这个代码块
file 'config/sass.rb', <<-RUBY
Sass::Engine::DEFAULT_OPTIONS[:load_paths].tap do |load_paths|
load_paths << "#{Rails.root}/app/assets/stylesheets"
load_paths << "#{Gem.loaded_specs['compass'].full_gem_path}/frameworks/compass/stylesheets"
end
RUBY
当我使用此模板运行'rails new'时,我收到以下错误:
undefined method `root' for Rails:Module (NoMethodError)
我是app模板以及此代码块语法的新手。 (你甚至称之为&lt;&lt; -RUBY阻止?在谷歌搜索真的很难)。我的印象是它不会运行块内的任何代码,所以它不应该导致错误。是什么给了什么?
更新:让我添加更多背景信息:
我正在尝试修改应用模板:https://github.com/leshill/rails3-app/blob/master/app.rb我想添加此博文中的代码:http://metaskills.net/2011/05/18/use-compass-sass-framework-files-with-the-rails-3.1-asset-pipeline/以便我可以在rails3.1中获得指南针支持
答案 0 :(得分:2)
详细说明mu的观点。
<<-SOMESTIRING
语法定义字符串的开头。该字符串以SOMESTRING
(在行的开头)终止
例如你看到了很多
string = <<-EOF
Hey this is a really long string
with lots of new lines
EOF
string # => " Hey this is a really long string\n\n with lots of new lines\n"
在这种情况下,RUBY
表示这是ruby代码(将被评估)。您必须记住,当在字符串内时,#{ruby_code}
转义语法将评估给定的ruby_code并将结果插入到字符串中。
所以为了解决这个问题,你可以做点什么,
irb >> s = <<-RUBY
"#{'#{Rails.root}'}/app/assets/stylesheets"
RUBY
#=> ""\#{Rails.root}/app/assets/stylesheets"\n"
这里我们使用#{}
打破字符串,然后使用单引号告诉ruby我们不希望评估#{Rails.root}
。
irb >> s= <<-RUBY
Rails.root.to_s + "/app/assets/stylesheets"
RUBY #=> "Rails.root.to_s + "/app/assets/stylesheets"\n"
这样我们就不必担心逃避了:)
答案 1 :(得分:1)
您要求“rails new”命令创建文件并使用“heredoc”传递内容块(由<<-SOMESTRING
语法表示)。关于heredoc的更多信息:
http://en.wikipedia.org/wiki/Here_document#Ruby
解析器将内容视为双引号包围的Ruby字符串,并尝试替换#{}
所包含的任何字符串。它失败了,因为它找不到名为Rails.root
的变量。
您可以使用single-quote-style-heredoc来避免替换行为(将内容视为由单引号包围的Ruby字符串)。用单引号围绕heredoc信号:
file'config / sass.rb',&lt;&lt; - 'RUBY'
Sass :: Engine :: DEFAULT_OPTIONS [:load_paths] .tap do | load_paths | load_paths&lt;&lt; “#{} Rails.root /应用/资产/样式” load_paths&lt;&lt; “#{Gem.loaded_specs [ '指南针']。full_gem_path} /框架/指南针/样式表” 端
RUBY
由于您正在为初学者应用创建Rails应用模板,因此查看
可能会有所帮助Rails 3.1 Application Templates 来自GitHub上的Rails Apps项目。
该项目提供了应用模板和文档的良好示例(请务必查看Thor::Actions和Rails::Generators::Actions)。