我试图让rails将目录的内容推送到Haml(作为字符串数组)并将它们作为链接呈现为链接文本,但无法弄清楚如何将多个实例变量传递给我哈姆文件.
这是我的控制器代码:
class FilesController < ApplicationController
def index
@dir = Dir.new('/Users/userName/Code/RailsTest/public/');
@files = Dir::entries('/Users/userName/Code/RailsTest/public/');
@fileNames = @files;
for file in @files
file = @dir.path + '/' + file
end
respond_to do |format|
format.html # index.html.haml
#format.xml { render :locals {:files => @files, :fileNames: @fileNames} }
format.xml { render :xml => @files }
end
end
end
和我的Haml文件:
%h1 Files
%p This will eventually list the files in our upload directory
- @files.each do |file|
%a(href=file) file
感谢您提供的任何帮助!
编辑:
我的控制器方法现在包含
@dir = Dir.new('/Users/chronon/DEsktop/RailsNexus/public');
@files = Dir::entries('/Users/chronon/DEsktop/RailsNexus/public');
@fileNames = @files;
@files.map! do |file|
{:path => "#{@dir.path}/#{file}", :filename => file}
end
respond_to do |format|
format.htm
end
index.html.haml和_file_link.html.haml都是nzifnab建议的.
但是,我现在在__file_link文件中得到’无法将符号转换为整数’错误.
两个haml文件的内容都是
%h1 Files
%p This will eventually list the files in our upload directory
= render :partial => 'files/file_link', :collection => @files, :as => :file
= link_to(:file[:path], :file[:filename])
(我必须将’file’更改为’:file’才能使渲染正常工作.基于Rails指南)
最佳答案 有两种方法可以执行此操作:将其渲染为部分或渲染正常输出模板.如果将其渲染为部分,则可以传递:locals选项哈希,您可以使用它来获取变量.如果渲染普通的haml文件,则需要使用数据的实例变量.
我会将控制器中的for循环更改为:
@files.map! do |file|
{:path => "#{@dir.path}/#{file}", :filename => file}
end
编辑:刚刚意识到你可能已经习惯了.map!方法.它将遍历@files中的每个条目,并将其值更改为块中最后一行的内容.如果你使用.map而不是.map!然后该方法将返回由这些值组成的新数组.
这只是一个类似ruby的东西,而且我不能100%确定你正在使用的for循环是否像你想要的那样通过引用来改变它.也许你的很好……但是我喜欢类似ruby的方法,比如Array.map,Array.each等,而不是for语法,这样就可以在漂亮的Hash中获得每个对象所需的所有数据.
您的haml文件可以更改如下:
index.html.haml
%h1 Files
%p Something exciting
= render :partial => 'files/file_link', :collection => @files, :as => :file
这将为@files数组中的每个对象呈现文件files / file_link.html.haml一次,并将该对象保存在本地变量文件中,如下所示:as =>选项.
然后你可以拥有这个文件:
_file_link.html.haml
= link_to(file[:path], file[:filename])
您在控制器中定义的任何实例变量都将自动在视图中可用.如果出于某种原因,你想让视图中的对象改为局部变量,我相信你必须将视图渲染为局部视图而不是完整视图.虽然它可能会这样做,但我不是100%肯定:
format.html{ render :action => 'index', :locals => {:files => files} }
然而,这不是一个很好的做法.通常在视图中直接使用控制器中的实例变量.希望我在这里的某处回答你的问题:)(你没有选项或参数的format.html足以支持我上面发布的视图代码).
编辑:
你是正确的改变渲染:部分到,:as => :file(符号在这里,我在上面更新).但是,它所做的是将@files数组中的每个项目作为名为file的新局部变量发送到partial.所以你的部分仍然应该说:
= link_to(file[:path], file[:filename])
还要记住,您不再需要@fileNames实例变量.地图!和哈希修复了这个问题.
在你调用@ files.map之后澄清一下!做…等等,你的数据结构应该是这样的:
@files = [
{:path => "my/path/1/filenamex", :filename => "filenamex"},
{:path => "my/path/2/filenamey", :filename => "filenamey"},
{:path => "my/path/3/filenamez", :filename => "filenamez"}
]
因此,当您将变量发送到render:partial =>它将为每个哈希渲染一次.第一个渲染,它将_file_link.html.haml中的文件变量设置为:
{:path => "my/path/1/filenamex", :filename => "filenamex"}
对于每个哈希值,它将经历三次.
我希望你明白发生了什么:)