Передача нескольких переменных в файл Haml в Rails? - PullRequest
4 голосов
/ 08 марта 2011

Я пытаюсь заставить rails отправлять содержимое каталога в Haml (в виде массива строк) и отображать их как ссылки с именами файлов в виде связанного текста, но пока не могу понять, как передать несколько экземпляров.переменные в мой файл 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 'для рендеринга для правильной работы. На основе этого из Rails Guides)

Ответы [ 2 ]

2 голосов
/ 08 марта 2011

Есть два способа сделать это: рендеринг как частичный или рендеринг нормального шаблона вывода.Если вы отобразите его как частичное, вы сможете передать хэш опций: 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, и это дает вам все данные, необходимые для каждого объекта в хорошем хеш-коде.

Ваш файл haml может быть изменен следующим образом:

index.html.haml

%h1 Files
%p Something exciting

= render :partial => 'files/file_link', :collection => @files, :as => :file

Это отразит файл files/file_link.html.haml один раз для каждого объекта, найденного в массиве @filesи сохраните этот объект в локальной переменной file, как указано в опции :as =>.

Тогда вы можете получить этот файл:

_file_link.html.haml

= link_to(file[:path], file[:filename])

Любые переменные экземпляра, которые вы определили в своем контроллере, будут автоматически доступны в представлении.Если бы по какой-либо причине вы хотели сделать объект в представлении вместо локальной переменной, вам, я полагаю, пришлось бы отображать представление как частичное, а не как полное представление.Хотя это может сработать, я не уверен на 100%.:

format.html{ render :action => 'index', :locals => {:files => files} }

Однако это не очень хорошая практика.Типично просто использовать переменные экземпляра из контроллера прямо в представлении.Надеюсь, я ответил на ваш вопрос где-то здесь :) (format.html, у вас нет параметров или параметров, достаточно для кода просмотра, который я разместил выше).

РЕДАКТИРОВАТЬ:

вы были правыизменить render :partial to, :as => :file (символ здесь, я обновил его выше).Однако он отправляет каждый элемент в массиве @files как новую локальную переменную с именем file в партиал.Таким образом, ваша часть должна по-прежнему говорить:

= link_to(file[:path], file[:filename])

Также имейте в виду, что вам больше не нужна переменная @fileNames экземпляра..map! и хеш исправили эту проблему для вас.

Чтобы уточнить, после того, как вы позвонили @files.map! do ... и т. д., ваша структура данных должна выглядеть примерно так:

@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 в _file_link.html.haml будет установлена ​​следующим образом:

{:path => "my/path/1/filenamex", :filename => "filenamex"}

И будет проходить ее три раза для каждого значения хеш-функции.

Iнадеюсь, вы понимаете, что происходит :) 1059 *

0 голосов
/ 08 марта 2011

Думаю, это то, что вы хотите

   @myfiles = [];
     for file in @files
           @myfiles << { :file => @dir.path + '/' + file, :filename => file}
     end

     respond_to do |format|
       format.html
     end
...