【问题标题】:Rails select form with the two options带有两个选项的 Rails 选择表单
【发布时间】:2012-01-29 00:40:20
【问题描述】:

我正在尝试创建一个上传表单,允许用户选择一个空白值,这将导致另一个上传过程。 (我用“class”代替了我的实际班级名称)

我的上传表单是

<%= 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!

我尝试了许多不同的技巧,我试图避免向数据库添加新列。提前致谢。

【问题讨论】:

  • 如何让用户将选择框留空,然后运行不同的上传方法?在上面的创建操作中,我尝试了 if .. else 条件。如果用户没有从选择框中选择选项,我希望第一个运行。

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

Kyle,如果选择了空白选项,我相信 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 所指出的,重构您发布的代码的空间很大。但是,如果您只是想让现有代码正常工作,这可能会有所帮助。

将来,当某些东西不工作时,而不是仅仅“破解它直到它工作”,查看日志/控制台输出以获取更多信息。将日志语句添加到控制器方法中,打印出变量的值等。然后尝试一下,并再次查看日志以了解方法内部发生了什么。

【讨论】:

  • @Kyle,这对你有用吗?如果有帮助,将不胜感激。
  • 它得到了我想要的。整个上传过程仍然没有奏效,因为我对拥有该 class_id 有一些其他依赖项。这与我在 S3 中存储文件的方式有关。
【解决方案2】:

如果两个上传之间的唯一区别是 :class =&gt; @class 对,则应该没有理由有两个单独的操作。

假设如下:

  • 我们正在这里处理 Upload 对象(upload.rb 模型,uploads_controller.rb 控制器)
  • Upload.factory 是一种处理器方法,用于处理和格式化上传数据,从而生成包含文件和元数据的完整 Upload 对象。

如果是这样,所有控制器逻辑都可以移到模型中。使用实例变量将数据传递给模型(通过attr_accessor,而不是通过添加列)。在factory 上添加before_create 过滤器,以便在保存之前处理您的上传。

使用验证来处理“无数据”错误。

这是一个例子。 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,然后保存记录。

【讨论】:

  • 感谢您的回答,我没有时间实施它,但您是对的。我需要将大部分内容整合到我的模型中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多