Rails file_field does not upload anything - ruby-on-rails

I am using Rails 4 and Ruby 2 with Carrier Wave along with jQuery Mobile 1.3, and a user has a profile which has a logo. I have tested the backend Carrier Wave stuff in the console and it works.
The problem is in the form helper, it doesn't matter what I do, but a file_field will display and let me choose an image, but it does not come through in the params. If I change it to a field that does not exist eg. =f.file_field :field_not_permitted_in_strong_params it does not fall over and a file picker is visible, if I change that to =f.text_field :field_not_permitted_in_strong_params, only then does rails kick in and complain about the field not existing.
So my problem is basically, I can upload a file client side, but it does not get sent through in the form data, or appear in the params hash, and all my other fields work correctly.
Here is a snippet of the form:
= form_for(#business_profile, :html => {:multipart => true}, :url => business_profile_path, :validate => true) do |f|
=image_tag(#business_profile.logo.url, class: 'business-logo')
%div{:data => {:role => 'fieldcontain'}}
=f.file_field :logo
- # Basic Information
%div{:data => {:role => 'collapsible', :collapsed => 'false'}}
%h3
Basic Information
%div{:data => {:role => 'fieldcontain'}}
= f.label :name, 'Business name:'
= f.text_field :name
%div{:data => {:role => 'fieldcontain'}}
= f.label :address, 'Address:'
= f.text_area :address, class: 'address'

OK after spending hours on the matter, the problem is that jQuery Mobile submits forms with Ajax by default, and files cannnot be submitted with Ajax without using plugins etc.
So the solution is to disable the Ajax like this:
= form_for(#business_profile, :url => business_profile_path, :validate => true, :html => { :'data-ajax' => false }) do |f|

Related

Attempting to upload multiple files returns array of nil values (Rails App)

I'm attempting to upload multiple files using a form inside a Rails 2.3.18 application. I've added :multipart => true to my form and :multiple => true to my file_field tag. The names portion of the file_field tag is images[].
I am able to add multiple images in the browser and successfully submit the form. However, the images portion of the params shows [nil, nil] in the controller for however many images I submitted. I've included the form below (it is written in HAML).
- form_for :message, :url => post_url, :html => { :multipart => true, :class => "order-details-form"} do |form|
= form.text_area :content, :placeholder => t(:type_message_here, :scope => :std)
= form.file_field 'images[]', :multiple => true
= form.submit t(:send, :scope => :bpt), :class => "io-button"

XSS prevention in rails input fields?

I have a user input form like
= simple_form_for(#user) do |f|
= f.input :about_me, :input_html => {"data-fileupload" => "false", :class => "span12 rich_regular"}, :label => _("about_me")
and the the field about_me is been sanitized at the model level like
sanitize_text :basic => [:about_me], :except => [:time_zone]
but, when i copy any js script like
<script>alert(hello)</script>
above alert it is beeing executed i.e, alert is being displayed. how should I prevent it from the front end

ajax:complete fires but ajax:success doesn't in a rails 3 app

I am new to RoR, but have decent success with implementing various features for a small app. Until I hit this issue.. for which haven't found any existing issues/questions. To help narrow down my problem to a generic form, here is what I have:
User Story
User is presented with a form to create topics (name & description), once topic is created user is presented the 'show' page which allows the user to add subtopics. As the user adds subtopics, they are shown to the user on the same page (this is where I am trying to use ajax).
Code Artifacts
model ==> topic_request.rb
class TopicRequest < ActiveRecord::Base
has_many :subtopics, :class_name=>"TopicRequest", :foreign_key=>"parent_id"
end
controller ==> topic_requests_controller.rb
class TopicRequestsController < ApplicationController
expose(:user_topic_requests) {current_user.topic_requests}
expose(:topic_request)
expose(:sub_topic_request) {TopicRequest.new}
def new
end
def create
topic_request.save
if (topic_request.parent_id != nil)
parentreq = TopicRequest.find(topic_request.parent_id)
render :partial => 'subreqs', \
:locals => {:topic_requests => parentreq.subtopics}, \
:layout => false
else
render :show
end
end
def show
end
def index
end
end
new.html.slim
= simple_form_for topic_request, :html => {:class => 'form-stacked'} do |f|
= f.error_notification
fieldset
= f.input :name, :required => true
= f.input :description, :required => true
.actions
= f.button :submit, "Propose Topic"
show.html.slim
# display the parent topic
= topic_request.name
= topic_request.description
#display the form for accepting subtopic requests
= simple_form_for sub_topic_request, \
:url => {:controller => "topic_requests", :action => "create"}, \
:remote => true, \
:html => {:class => 'form-stacked', \
:id => 'new_subtopic_request'} do |f|
= f.error_notification
fieldset
= f.input :name, :required => true
= f.input :description, :required => true
= f.input :parent_id, :as => :hidden,\
:input_html => {:value => topic_request.id}
.actions
= f.button :submit, "Propose Subtopic", \
:class => "btn", :disable_with => "Please wait..."
#subtopic_requests
= render :partial => 'topic_requests/subreqs', \
:locals => {:topic_requests => topic_request.subtopics}
partial ==> _subreqs.html.slim
- topic_requests.each do |onereq|
= onereq.name
= onereq.description
hr
coffeescript ==> topic_requests.js.coffee
jQuery ->
new_subreq_form = $("#new_subtopic_request")
if new_subreq_form.length > 0
new_subreq_form.bind 'ajax:before', (e) ->
# console.log 'ajax:before'
new_subreq_form.bind 'ajax:success', (event, data, status, xhr) ->
$("#subtopic_requests").html(data)
new_subreq_form.bind 'ajax:failure', (xhr, status, error) ->
# console.log 'ajax:failure'
new_subreq_form.bind 'ajax:error', (xhr, status, error) ->
# console.log 'ajax:error' # parseerror eg
new_subreq_form.bind 'ajax:complete', ->
$("#topic_request_name").val("")
$("#topic_request_description").val("")
Problem
The subtopic creation happens, I see new records in database. The clearing of fields from 'ajax:complete' binding also happens just fine, I see those input fields clearing up. I see topic_requests/_subreqs.html.slim completing with status 200. The 'show' page however is not showing the results of rendering the partial, which is what I am trying to capture in the 'ajax:success'.
Any ideas to help debug or samples that I refer to do this is greatly appreciated.
Rails 4 solution: add data {type: 'text'}:
= form_for vendor, :remote => true, data: {type: 'text'}
This adds the data-type="text" attribute to the form, which jquery-ujs passes to jQuery's ajax method as parameter dataType.
According to the docs of jQuery's ajax method:
if dataType is not specified if is inferred intelligently
if json is inferred, the response is parsed into a Js object and returns a parse error on error
This is probably what is happening given the parseerror output you get from 'ajax:error'.
I had the same problem and I did it works writing explicitly the format type of the request
for example
= form_for vendor, :format => :html, :remote => true, :html => {:class => "form form-edit", :'data-widget' => 'edit-vendor-form'} do |f|
If I don't use :format in that way then I have the same issue that you have.
I hope help. Regards.
In my code I have found that any ajax response needs to specifically include :content_type => 'text/json' for ajax:success to ever fire. It's weird but unless your response explicitly includes this it seems the browser doesn't always handle it correctly (esp. firefox).
I don't know if you can apply that to fix your situation exactly, but I hope that information helps.

Problems with jquery sexy post, javascript response and placeholder attribute

I'm currently working on a rails app in which I have a form which is submitted with jquery sexy post and gets back a js response, the code below was working fine but after I added the placeholder attribute for some reason it got broken.
= form_for [#room, #room.messages.new], :html => { :multipart => true } do |f|
= f.text_area :text, :size => "60x1", :class => "field", :placeholder => "say something"
= f.submit "Send"
= f.file_field :image, :class => "img_field"
= link_to "Add Image", "#", :id => "add_imgLink"
The form is being submitted and we get the answer back from the server, though, the js response is not being executed and the form is not being refreshed, any idea what of what could be possible going wrong ?
Thanks!
--
UPDATE:
Just find out that if I replace :placeholder by :value, it does works, but if I don't include :value it doesn't.
UPDATE2:
I found the problem and it wasn't related with jquery, rails or js, one of my coworkers modified sexypost and introduced a bug. Problem fixed.
I'd guess the space in the string. Try url encoding it.

Populate form fields using a dropdown and AJAX with Rails

I have a form field where a user enters contact information, including name, email, etc. If they already have contacts saved I want to have a dropdown with their saved contacts. When a contact from the dropdown is selected, the contact fields should be populated with that data to allow for easy editing.
For some reason this approach isn't working:
In my new.html.erb view:
<%= f.collection_select :id, #contacts, :id, :name, :onchange =>
remote_function(:url =>{:action => 'populate_contact_form'}, :with => 'id') %>
In my controller:
def populate_contact_form
raise "I am working up to this point"
#contact = current_account.contacts.find(params[:id])
end
In populate_contact_form.rjs:
page['contact_name'].value = #contact.name
page['contact_email'].value = #contact.email
It seems my controller method is never called... can anyone explain how to do this?
It's not getting called because you're using remote_function incorrectly. Rails assumes the current action/controller/id/etc if any of those options are missing from the :url option to remote_function. You're passing :action as a top level option to remote_function, and it gets ignored. With a :url option Rails assumes the same action and controller that rendered this view.
This should fix your problem:
<%= f.collection_select :id, #contacts, :id, :name, :onchange =>
remote_function(:url =>{:action => 'populate_contact_form'}, :with => 'id') %>

Resources