Рельсы выбирают форму с двумя вариантами - PullRequest
0 голосов
/ 29 января 2012

Я пытаюсь создать форму загрузки, которая позволяет пользователю выбрать пустое значение, которое затем приведет к другому процессу загрузки. (я заменил в «классе» свое фактическое имя класса) .

Моя форма загрузки

<%= form_for @upload, :url => class_uploads_path(@uploader), :method =>            
 :post, :html =>{ :multipart => true } do |f| %>
<%= render "shared/error_messages", :target => @upload %>

  <p>This media relates to...<br/>
 <%= select "upload", "class_id", Class.all.collect {|class| [class.name,class.id] }, {        
  :include_blank => true } %></p>

  <p>Title:<br/>
  <%= f.text_field :title %></p>

 <p>Description:<br/>
  <%= f.text_area :description, :rows => 3 %></p>

 <p>File to upload:<br/>
  <%= f.file_field :data %></p>

  <p><%= f.submit 'Upload for review' %></p>
   <% end %>

Вот мой метод создания, если пользователь оставляет поле выбора пустым, я бы хотел, чтобы первое действие загрузки было выполнено, и если он выбрал класс, я хочу, чтобы вторая загрузка была запущена.

def create          
  upload_params = params[:upload] || params[:image] || params[:video]
   @class = Class.find(upload_params[:class_id]) || nil

  begin
    if upload_params[:data]
      file_name = upload_params[:data].original_filename
      file_contents = upload_params[:data].read
    end
  rescue
    @upload = Upload.new
    flash[:error] = "Could not find upload file data.  Please reselect file."
    render :action => 'new' and return
  end

  begin
    if @class.nil?
            @upload = Upload.factory({ :file => file_contents, 
                                        :name => file_name, 
                                        :network => @uploader,
                                        :title => upload_params[:title],
                                        :description => upload_params[:description] })
    else
         @upload = Upload.factory({ :file => file_contents, 
                                        :name => file_name, 
                                        :class => @class,
                                        :network => @uploader,
                                        :title => upload_params[:title],
                                        :description => upload_params[:description] })
    end
    @upload.save!

Я пробовал несколько разных хаков, я стараюсь не добавлять новый столбец в базу данных. Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 30 января 2012

Кайл, если выбран пустой параметр, я считаю, что params [: class_id] должен быть "" (пустая строка). Вы должны проверить это - посмотрите в своих журналах разработки и посмотрите, какие параметры передаются обратно в ваш метод контроллера, как когда вы выбираете класс, так и когда вы этого не делаете.

Если это правильно:

class_id = params[:class_id]
@class   = Class.find(class_id.to_i) if class_id and not class_id.empty?

Как указал gg_s, есть много места для рефакторинга кода, который вы разместили. Но если вы просто хотите, чтобы существующий код работал, это может быть полезно.

В будущем, когда что-то не работает, вместо того, чтобы просто «взломать его до тех пор, пока оно не заработает», посмотрите на вывод logs / console для получения дополнительной информации. Добавьте операторы ведения журнала в метод контроллера, распечатав значения переменных и т. Д. Затем попробуйте его и снова посмотрите журналы, чтобы увидеть, что происходит внутри метода.

0 голосов
/ 30 января 2012

Если единственной разницей между загрузками является пара :class => @class, не должно быть оснований для двух отдельных действий.

I предполагает следующее:

  • Здесь мы работаем с Upload объектами (upload.rb модель, uploads_controller.rb контроллер)
  • Upload.factory - это процессорный метод, который обрабатывает и форматирует загружаемые данные, что приводит к полному Upload объект с файлом и метаданными.

Если это так, вся эта логика контроллера может быть перемещена в модель.Передайте данные в модель с переменными экземпляра (через attr_accessor, а не путем добавления столбцов).Установите before_create фильтр на factory, чтобы он обрабатывал загрузку перед сохранением.

Используйте проверки для обработки ошибок «нет данных».

Вот пример.upload.rb:

before_create :factory # run your factory method before creating

attr_accessor :form_data, :form_network, :form_title, \ # settable from controller
              :form_description, :form_class_id

validates :form_data, :presence => true, :on => :create, \  # fail if no data
          :message => "No file data.  Please reselect file."

private

def factory
  file_name = self.form_data.original_filename
  file_contents = self.form_data.read
  class = Class.where(:id => self.form_class_id).first # returns Class or nil
  # if class is nil, handle it however you need to here
  # access self.form_network, self.form_title, self.form_description directly

  # ... factory magic ...
end

Теперь ваш контроллер может быть таким аккуратным, как это:

def create
  upload_params = params[:upload] || params[:image] || params[:video]

  @upload = Upload.new({ :form_data        => upload_params[:data], 
                         :form_network     => @uploader, # <-- undefined!
                         :form_class_id    => upload_params[:class_id],
                         :form_title       => upload_params[:title],
                         :form_description => upload_params[:description]})
  if @upload.save
    redirect_to @upload
  else
    render :action => "new"
  end
end

Обратите внимание, что @uploader не определено.

@upload.save подтвердит @upload.Если данные файла отсутствуют, save не удастся, и вы вернетесь к действию new с сообщением об ошибке «нет данных».В противном случае, если проверка прошла успешно, вызывается factory, тогда запись сохраняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...