CHsurfer
CHsurfer

Reputation: 1414

Upload multiple files in form with ruby mechanize

I can successfully upload a single file using a Mechanize form like this:

def add_attachment(form, attachments)
   attachments.each_with_index do |attachment, i|
     form.file_uploads.first.file_name = attachment[:path]
   end
end

where form is a mechanize form. But if attachments has more than one element, the last one overwrites the previous ones. This is obviously because I'm using the first accessor which always returns the same element of the file_uploads array.

To fix this, I tried this, which results an error, because there is only one element in this array.

def add_attachment(form, attachments)
   attachments.each_with_index do |attachment, i|
     form.file_uploads[i].file_name = attachment[:path]
   end
end

If I try to create a new file_upload object, it also doesn't work:

def add_attachment(form, attachments)
   attachments.each_with_index do |attachment, i|
     form.file_uploads[i] ||=  Mechanize::Form::FileUpload.new(form, attachment[:path])
     form.file_uploads[i].file_name = attachment[:path]
   end
end

Any idea how I can upload multiple files using Mechanize?

Upvotes: 1

Views: 582

Answers (2)

bobish
bobish

Reputation: 11

I used the following

form.file_uploads[0].file_name = "path to the first file that to be uploaded"
form.file_uploads[1].file_name = "path to the second file that to be uploaded"
form.file_uploads[2].file_name = "path to the third file that to be uploaded".

and worked fine. Hope this helps.

Upvotes: 0

CHsurfer
CHsurfer

Reputation: 1414

So, I solved this issue, but not exactly how I imagined it would work out.

The site I was trying to upload files to was a Redmine project. Redmine is using JQueryUI for the file uploader, which confused me, since Mechanize doesn't use Javascipt. But, it turns out that Redmine degrades nicely if Javascript is disabled and I could take advantage of this.

When Javascript is disabled, only one file at time can be uploaded in the edit form, but going to the 'edit' url for the issue that was just created gives the chance to upload a second file. My solution was to simply attach a file, upload the form and then click the 'Update' link on the resulting page, which presented a page with a new form and another upload field, which I could then use to attach the next file to. I did this for all attachments but the last, so that the form processing could be completed and then uploaded for a final time. Here is the relavant bit of code:

def add_attachment(agent,form, attachments)
  attachments.each_with_index do |attachment, i|
    form.file_uploads.first.file_name = attachment[:path]
    if i < attachments.length - 1
      submit_form(agent, form)
      agent.page.links_with(text: 'Update').first.click
      form = get_form(agent)
    end
  end
  form
end

Upvotes: 2

Related Questions