I'm working on creating a new edit/update view and routes for a fairly large Rails (v4.0.3) app. I'm using remote: true to submit sections of the form without reloading the whole page, and then simply replacing the form HTML with the response HTML (which is the form partial). The URL (.../edit) should remain the same.
It works fine to update text fields, but when I upload an image (using Carrierwave) I get this strange behavior where the image uploads fine but then I get redirected to the controller action URL (.../update) and the browser displays the raw partial out of context.
Here's the relevant method from my resource controller:
def update
respond_to do |format|
if #provider.update_attributes(admin_provider_params)
if params[:provider][:logo]
#provider.logo = params[:provider][:logo]
#provider.save
elsif params[:provider][:remove_logo] == '1'
#provider.remove_logo!
#provider.save
end
format.html { render partial: "provider_form", locals: { provider: #provider } }
format.json { render json: #provider }
else
format.html { render action: "edit" }
format.json { render json: #provider.errors, status: :unprocessable_entity }
end
end
end
And here's some selected code from my view partial:
= simple_form_for [:admin, #provider],
remote: true,
html: { class: 'form-horizontal', multipart: true, id: 'provider-data-form' },
authenticity_token: true,
wrapper: :horizontal_form do |f|
-# (SOME OTHER FORM FIELDS HERE)
-# LOGO UPLOAD ELEMENTS
.form-group.file.optional.provider_logo
= f.input :logo, input_html: { id: "provider-logo-upload-real", class: "hidden"}, :as => :file, wrapper: false
%button#provider-logo-upload-btn= #provider.logo_url.nil? ? "Upload Logo" : "Replace Image"
%img#logo-upload-img{src: #provider.logo_url}
-# SUBMIT FORM
= f.button :submit, translate_helper(:save), id: "save-provider-form-btn"
:javascript
$(document).ready(function() {
// Handle logo upload via proxy button
$('#provider-logo-upload-btn').on("click", function(e) {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
$('#provider-logo-upload-real').click();
});
// Preview logo before upload
$('#provider-logo-upload-real').change(function(e) {
$('#logo-upload-img').attr("src", URL.createObjectURL(event.target.files[0]));
});
// Handle Form submit
$('#provider-data-form')
.on("ajax:success", function(evt, data, status, xhr) {
console.log("AJAX Success!", arguments);
// On success, refresh just the provider form partial
$('#provider-data-form').replaceWith(xhr.responseText);
});
});
I think this is all the relevant code, but I'm happy to provide more on request. There's not much additional logic tacked on the CarrierWave Uploader classes.
Finally, here are my server logs (edited slightly for brevity) when I submit the form with a new image for upload:
I, [2016-10-17T10:09:24.745387 #1219] INFO -- : Started PATCH "/en/admin/providers/8" for 127.0.0.1 at 2016-10-17 10:09:24 -0400
I, [2016-10-17T10:09:24.754005 #1219] INFO -- : Processing by Admin::ProvidersController#update as JS
I, [2016-10-17T10:09:24.754133 #1219] INFO -- : Parameters: application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01", "locale"=>"en", "id"=>"8"}
I, [2016-10-17T10:09:24.754187 #1219] INFO -- : Parameters: {
// LISTS PARAMETERS, INCLUDING IMAGE UPLOAD DATA
}
I, [2016-10-17T10:09:25.105809 #1219] INFO -- : Rendered admin/providers/_provider_form.html.haml (52.9ms)
I, [2016-10-17T10:09:25.106381 #1219] INFO -- : Completed 200 OK in 352ms (Views: 43.8ms | ActiveRecord: 51.8ms)
// IF NO IMAGE WAS INCLUDED, NORMALLY IT STOPS AT THIS POINT, BUT...
I, [2016-10-17T10:09:25.111315 #1219] INFO -- : Started PATCH "/en/admin/providers/8" for 127.0.0.1 at 2016-10-17 10:09:25 -0400
I, [2016-10-17T10:09:25.122752 #1219] INFO -- : Processing by Admin::ProvidersController#update as HTML
I, [2016-10-17T10:09:25.122925 #1219] INFO -- : Parameters: {
// LISTS PARAMETERS, NO IMAGE UPLOAD DATA
}
I, [2016-10-17T10:09:25.268027 #1219] INFO -- : Rendered admin/providers/_provider_form.html.haml (43.9ms)
I, [2016-10-17T10:09:25.268360 #1219] INFO -- : Completed 200 OK in 145ms (Views: 35.2ms | ActiveRecord: 39.5ms)
// PAGE DISPLAYS PARTIAL ONLY, URL IS FOR UPDATE ROUTE RATHER THAN EDIT
Sorry for such a long question; I've been puzzled by this for over a week. I'd appreciate any help I can get!
I guess that is because Rails remote form with file falls back to HTML submission instead of regular JS submission . Try using remotipart Gem.
Okay, I think I've been able to solve it. Thanks to #sajan, I found this issue on the Remotipart github page: https://github.com/JangoSteve/remotipart/issues/129
By preventing default on my submit button click events and then submitting the form itself, I was able to stop the multiple form submit issue.
I'm following the Beginning Rails 3, Updated book from Apress 2010. The problem I'm having is with loading a Template dynamically with Ajax using the jQuery adapter. Everything works but it appears to be rendering three times on the page.
Here is how I dynamically load it when the user clicks the "new comment" link.
views/articles/show.html.erb
<%= link_to "new comment",
new_article_comment_path(#article, :format => :js),
:remote => true,
:id => 'new_comment_link' %>
Then I render it as such.
views/comments/new.js.erb
$("<%= escape_javascript render :file => 'comments/new'," +
" :formats => [:html], :handlers => [:erb] %>")
.insertAfter('#comments');
Then I see this in the log.
Started GET "/articles/1/comments/new.js" for 127.0.0.1 at 2013-01-18 14:51:05 -0600
Processing by CommentsController#new as JS
Parameters: {"article_id"=>"1"}
Article Load (0.2ms) SELECT "articles".* FROM "articles" WHERE "articles"."id" = ? LIMIT 1 [["id", "1"]]
Rendered comments/new.html.erb (53.8ms)
Rendered comments/new.js.erb (54.6ms)
Completed 200 OK in 57ms (Views: 55.9ms | ActiveRecord: 0.2ms)
Notice it renders my erb and the js file? Somehow that ends up with showing up three times on my page.
Any clues on how to fix this? I'm using Rails 3.2.9, rails.js (latest), and jquery-1.9.0.
Thanks!
Solved it!
Turns out I was adding rails.js and jquery.js TWICE!
Here is the skinny: assets/javascripts/application.js is crucial for including javascript files into your app. Basically whatever gets defined there gets pushed out to the page. You simply need to make sure that it gets defined at least once in the app as such.
views/layouts/application.html.erb
<%= javascript_include_tag "application" %>
And that's it! The Ajax jQuery adapter should just work. Becareful not to add any additional files to the javascript folder as those will get pushed out as well and that's exactly what you don't want. Basically I was defining the adapter both through application.html.erb and manually by downloading both files. Hopefully this will help a lost poor soul somewhere along the way.
Happy Hacking.
This is an issue I have been working around for some time now thinking I would eventually stumble on an explaination. I have not and it's now becoming a little more problematic for me.
I used rails-generate-scaffold to create a simple (users and posts) application. This was done after installing jquery and jquery-ui. I added actions "login" and "auth" to the users controller. Login.html.erb contains some javascript that sends .ajax request to the users#auth action passing the login information (email and password) as parameters.
The the template auth.js.erb exists. The "auth" action responds to format.js. The request looks normal, but rails processes the request with the "show" action rather than the "auth" action.
In other words, a request to userscontrollers#auth (via .ajax) is being processed by userscontroller#show (as JS).
The problem goes away if I remove the "resources :users" route that scaffold added (the correct action is then called). But without this route other useful scaffold stuff becomes unuseable (like users#new).
From Gemfile: gem 'jquery-rails', '>=0.2.6'
Installed jQuery with: rails generate jquery:install --ui
From ../layouts/application.html.erb
<head>
<title>Tab1</title>
<%= stylesheet_link_tag :all %>
<%= stylesheet_link_tag 'jquery-ui-1.8.16.custom.css' %>
<%= javascript_include_tag :defaults %>
<%= javascript_include_tag 'jquery.min.js' %>
<%= javascript_include_tag 'jquery.min.js', 'jquery-ui.min.js' %>
<%= csrf_meta_tag %>
</head>
Here is ./log/development.log to shows the request and the response.
Started GET "/users/auth/?email=steve&password=[FILTERED]&_=1326063255777" for 24.11.242.181 at 2012-01-08 17:53:45 -0500
Processing by UsersController#show as JS
Parameters: {"email"=>"steve", "password"=>"[FILTERED]", "_"=>"1326063255777", "id"=>"auth"}
^[[1m^[[36mUser Load (0.2ms)^[[0m ^[[1mSELECT `users`.* FROM `users` WHERE `users`.`id` = 0 LIMIT 1^[[0m
Completed 404 Not Found in 6ms
ActiveRecord::RecordNotFound (Couldn't find User with ID=auth):
app/controllers/users_controller.rb:43:in `show'
Suggests that the request --> GET "/users/auth/?email ... is being processed by UsersController#show as JS
Thanks
im trying to get AMF to work with Rails3.
I have succesfully installed rails3-amf-0.1.0 gem and the RocketAMF-0.2.1 gem.
In my app there is a controller with the following code:
def getRandomCards
#incoming = params[0]
#cards = Cardvo.first
respond_with(#cards) do |format|
format.amf { render :amf => #cards.to_amf}
end
end
through a call from Actionscript i would like to return some data in amf format.
further more, as mentioned in the instructions for rails3-amf i did the following.
in my production.rb under config/environment i added the line
config.rails3amf.map_params :controller => 'CardvosController', :action => 'getRandomCards'
an my amf gateway got
config.rails3amf.gateway_path = "/gateway"
The problem is:
Any call from Actionscript / Flash raises the following
(taken from the log )
Started POST "/gateway" for 192.178.168.1 at Fri Nov 19 15:13:28 +0100 2010
Processing by CardvosController#getRandomCards as AMF
Parameters: {0=>100.0}
[1m[36mSQL (0.4ms)[0m [1mSHOW TABLES[0m
[1m[35mCardvo Load (0.2ms)[0m SELECT `cardvos`.* FROM `cardvos` LIMIT 1
Completed 200 OK in 13ms (Views: 0.9ms | ActiveRecord: 0.5ms)
NoMethodError (undefined method `constructed?' for #<RocketAMF::Envelope:0x39ba868>):
The Amf file is created but the method, which is in remoting.rb from RocketAMF could not be found.
I think the error is thrown at request_parser.rb from Rails3AMF asking for constructed?
# Wrap request and response
env['rack.input'].rewind
env['rails3amf.request'] = RocketAMF::Envelope.new.populate_from_stream(env['rack.input'].read)
env['rails3amf.response'] = RocketAMF::Envelope.new
# Pass up the chain to the request processor, or whatever is layered in between
result = #app.call(env)
# Calculate length and return response
if env['rails3amf.response'].constructed?
For me it seems it is looking at the wron class for the method.
Where
NoMethodError (undefined method `constructed?' for #RocketAMF::Envelope:0x39ba868):
the essential part is
RocketAMF::Envelope:0x39ba868
which should be
RocketAMF:ANOTHER_CLASS:Envelope:0x39ba868
Am i right and where the heck is the error ?
Any help would be appreciated!
chris
I'm diving into Ruby on Rails and I'm experiencing a weird bug, using Rails 3.0.1 and Ruby 1.8.7. Using the generated scaffold code, my "Show" action is getting called when I'm expecting my "Destroy" action to get called. Here's the code...
routes.rb
webappdotcom::Application.routes.draw do
resources :projects
root :to => "home#index"
end
index.html.erb
<td><%= link_to 'Destroy', project, :confirm => 'Are you sure?', :method => :delete %></td>
actual HTML code that is rendered in browser
<td>Destroy</td>
server output when I click on the "Destroy" link
Started GET "/projects/12" for 127.0.0.1 at Wed Oct 20 23:39:37 -0500 2010
Processing by ProjectsController#show as HTML
Parameters: {"id"=>"12"}
Project Load (0.1ms) SELECT "projects".* FROM "projects" WHERE ("projects"."id" = 12) LIMIT 1
Rendered projects/show.html.erb within layouts/application (9.0ms)
Completed 200 OK in 77ms (Views: 13.3ms | ActiveRecord: 0.1ms)
You can see the "ProjectsController#show" action is being called, but I want the "Destroy" action to be called. Also, I noticed the browser isn't displaying the confirmation message "Are you sure?" either. Any ideas what could be causing this or what I'm missing?
Thanks so much!
This is because Rails 3 changed the way it uses javascript in forms. It used to add an onclick method to the link, but that goes against unobtrusive javascript. Now it just sets some tag attributes, and hooks into it with javascript in another file.
That page's layout (which is probably application.html.erb unless you've changed it) needs to have this line in the head section:
<%= javascript_include_tag :defaults %>
If this line is missing from your layout, that's the problem. Another possible cause could be if you've added the jQuery library to your app without adding the rails-specific jQuery library. Let me know how this works.
This may help you link_to with :method=>:delete not working ( Rails 3 ). Although in that article the edit is getting called instead. But the solution should work for show as well.