Cannot get page to redirect? - ruby-on-rails

I'm using Rails 4 and Dropzone.js to drag and drop files and upload them on form submission. I don't know why I can't get this to work but I'm trying to redirect after the form submits to a certain page but its not doing it (everything saves correctly though).
Here is my code:
items/new.html.haml > _form.html.haml
= form_for #item, validate: true,
html: {id: 'item-form', class: 'form-horizontal form', multipart: true} do |f|
= f.text_field :name
%main#image-preview
#dropzone
.fallback
= f.file_field :image, multiple: false
= f.submit 'Done', id: 'item-submit'
items.coffee
Dropzone.autoDiscover = false
if document.getElementById('item-form')
dropzone = new Dropzone('#item-form',
maxFiles: 1
maxFilesize: 1
paramName: 'item[image]'
headers: "X-CSRF-Token" : $('meta[name="csrf-token"]').attr('content')
addRemoveLinks: true
clickable: '#image-preview'
previewsContainer: '#image-preview'
thumbnailWidth: 200
thumbnailHeight: 200
autoProcessQueue: false
uploadMultiple: false)
$('#item-submit').on 'click', (e) ->
e.preventDefault()
e.stopPropagation()
if dropzone.getQueuedFiles().length > 0
dropzone.processQueue()
else
$getScript '/items'
return
items_controller.rb
def continue
#item = Item.find(params[:id])
if #item.user_id == current_user.id
respond_to do |format|
format.html
format.xml
format.json { render :json => {} }
end
end
end
def new
#item = current_user.items.build
end
def create
#item = current_user.items.build(item_params)
respond_to do |format|
if #item.save
format.json { render :json => "window.location = #{post_continue_item_path(#item).to_json}" }
else
format.html { render :new }
format.json { render json: #item.errors, status: :unprocessable_entity }
end
end
end
routes.rb
resources :items do
get '/post/continue', to: 'items#continue', on: :member
end
log
Started POST "/items" for 127.0.0.1 at 2015-10-06 12:23:35 -0700
Processing by ItemsController#create as JSON
............
Completed 200 OK in 1786ms (Views: 0.2ms | ActiveRecord: 10.6ms)
Not sure where to go with this so how do I redirect when its giving me a JSON call?

JSON is not Javascript. It is designed to pass some data, not a working code. Check the response with your browser's developer tools, you will see your 'window.location' script nicely wrapped and basically unable to do anything - it should come as a mere string.
If you want a pure, classical HTTP redirect, you should look into redirect_to Rails method as your only response, and never try to render a JSON when you actually need a redirect.

Related

rails object expected got string in association

I have this:
<%= f.association :gestor, selected: current_usuario.gestor_id, label_method: :descricao, value: current_usuario.gestor_id, disabled: true %>
My controller:
def create
#usuario = Usuario.new(usuario_params)
respond_to do |format|
if #usuario.save
format.html { redirect_to controle_usuarios_path, notice: 'Usuario was successfully updated.' }
format.json { render :index, status: :ok, location: #usuario }
else
format.html { render :new }
end
end
end
(...)
def usuario_params
params.require(:usuario).permit(:cpf, :usuario_pai, :gestor_id, :email, :password, :password_confirmation, :agente_id, :perfil_id)
end
And console:
Processing by ControleUsuariosController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"xnMQOvRLO3cCrq/l5KSSG0qB3Pc8S4wtSgs4PTCTkaJ5kLLwMD73s/4TeBWYYbvmBKzvBca4T0eMT9F9UQo/Ew==", "usuario"=>{"usuario_pai"=>"admin#mail.com", "agente_id"=>"2", "cpf"=>"111.111.111-11", "email"=>"xxx#xxx.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "perfil_id"=>"2"}, "commit"=>"Criar Usuario"}
The params gestor_id don't come, why? The error is this:
Usuario(#70271925151780) expected, got String(#3432540)
Rails is looking for gester_id and you are passing in gester as the param so it is being removed. Try changing it in your view to gester_id or in your params filter to gester.

Response for Form with custom action using ajax

I want to upload the user avatar (carrierwave) using a custom action like this:
= form_for user, url: update_user_avatar_path(id: user.id), :html => {:class => "up-cl-ava-form", data: {type: :json}, novalidate: true, method: :put}, remote: true do |f|
= f.file_field :avatar_picture
= f.submit "Update", remote: true
In UsersController
def update_user_avatar
#user = User.find(params[:id]) || current_user
respond_to do |format|
if #user.update_attributes!(avatar_picture: params[:user][:avatar_picture])
format.json { render json: {}, status: :ok}
else
format.json { render json: {}, status: :unprocessable_entity}
end
end
end
Params in #update_user_avatar
{"utf8"=>"✓", "_method"=>"put",
"authenticity_token"=>"BPGeN5mpRCYwIco1YSsBx6IT7MfIBOdSlwS9Y5WJZeU=",
"user"=> {"avatar_picture"=>
#>}, "commit"=>"Update", "id"=>"30", "action"=>"update_user_avatar",
"controller"=>"users"}
Request
.... "CONTENT_TYPE"=>"multipart/form-data;
boundary=----WebKitFormBoundaryvz51HFYrromiuTS7" ....
In my JS
$(document).ready(function(){
$(".up-cl-ava-form").on("ajax:success", function(){
alert("success")
});
});
The problem here is that the image is uploaded correctly but the site redirects to lvh.me:3000/update_user_avatar?id=30 (blank page), instead staying in the same view.
This will be solve by adding remotipart gem
https://github.com/JangoSteve/remotipart

Setting an object attribute from a hidden field Ruby on Rails

I'm trying to update an Idea attribute challenge_id through a hidden form field. Here is the field:
<%= f.hidden_field :challenge_id, :value => #challenge.id %>
It successfully passes the challenge id as a param when an idea is created to the Idea Controller#create method:
Started POST "/ideas.js" for ::1 at 2015-06-18 15:39:49 -0400
Processing by IdeasController#create as JS
Parameters: {"utf8"=>"✓", "idea"=>{"title"=>"adsf", "description"=>"asf", "domain_tokens"=>"20", "challenge_id"=>"5"}, "commit"=>"Create Idea"}
This challenge_id => 5 should then be saved to the idea in the line #idea = Idea.new(idea_params) below:
ideas_controller.rb
def create
#idea = Idea.new(idea_params)
respond_to do |format|
if #idea.save
idea_count = #idea.user.ideas_created_count
#idea.user.update(:ideas_created_count => idea_count + 1)
#idea.domains.each do |domain|
current_user.add_points(1, category: domain.title)
end
#ideas = current_user.current_team.ideas.sort_by{|i| i.heat_index}.reverse
#ideas = #ideas.paginate(:page => params[:ideas_page], :per_page => 10)
format.html { redirect_to :back, notice: 'Idea was successfully created.' }
format.json { render :show, status: :created, location: #idea }
format.js
else
format.html { redirect_to :back, notice: "You must attach domains to your Idea." }
format.json { render json: #idea.errors, status: :unprocessable_entity }
format.js { render :create_failed }
end
end
end
.
.
def idea_params
params.require(:idea).permit(:title, :description, :challenge_id)
end
However, this challenge id isn't being saved to the idea with the other permitted idea_params, :title and :description. How can I get challenge_id to be saved to the Idea when it's created?
Instead of using hidden field, why not pass in the challenge_id in your form? Otherwise, you leave open the possibility that users can enter whatever they want in that hidden field.
Form:
form_for [#challenge, Idea.new] do |f|
And then:
def create
#challenge = Challenge.find(params[:challenge_id])
#idea = Idea.new(idea_params)
#idea.challenge_id = #challenge.id
end
I'm assuming you have challenge_id column in ideas table.
Try something like:
def create
#idea = Idea.new(idea_params)
#idea.challenge_id = params[:idea][:challenge_id]
#...
end
If you params or column you want to save it to is different, make sure to make the change, but you get the idea.

Ajax success event in Rails 3

Rails newbe here. I've got links that do ajax query to server:
<%= link_to g.name, g, :class => 'link link-to-gallery', :remote => true %>
JS view that loads data from partial:
$('#content').html('<%= escape_javascript render("layouts/galleries/show") %>');
And controller that operates with models and renders html and js:
class GalleriesController < ApplicationController
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html
format.js
end
end
end
Ajax works fine, but I try to put callback after ajax completed:
jQuery(function() {
$(".link-to-gallery").bind("ajax:complete", function() {
alert(1)
});
});
and alert never shows. What am I doing wrong? Rails version is 3.2.11, Ruby version is 1.9.3p194
Update: When I'm using this code
jQuery(function() {
$(".link-to-gallery")
.on("ajax:before", function () {
alert("before")
})
.on("ajax:complete", function() {
alert("complete")
});
});
"before" alert fires but only once. If I press again I gain nothing. But ajax still works.
I think the problem is with your controller method that is not responding the async call with a success status message, 200.
Try this
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html { :status => 200 }
format.js { :status => 200 }
end
end
If that doesn't work, try this.
def show
#galleries = Gallery.all
#gallery_to_show = Gallery.find(params[:id])
respond_to do |format|
format.html { :status => :ok }
format.js { :status => :ok }
end
end
It seems that I'm lame but smart enough to fix this. I had these links:
<%= link_to g.name, g, :class => 'link link-to-gallery', :remote => true %>
in the partial which gets re-rendered after ajax. So the callback functions that were attached to these links were flushed away after ajax. So I put link out of this partial and it works now.

Test rails controller that respond in different formats

I have the following function in controller
def by_xy
#obj = BldPoly::find_by_xy(:x => params['x'], :y => params['y'])
respond_to do |format|
format.html { render :layout => false }
format.xml { render :layout => false }
format.json { render :layout => false }
end
and planning to write the automatic test in the following way
xml = nil
get :by_xy, {:x => 4831, :y => 3242, :format => :json}
assert_nothing_thrown { xml = REXML::Document.new(#response.body) }
td = REXML::XPath.first(xml, "//result/item")
assert_equal need_value, td.value
and I get
Completed in 50ms (View: 0, DB: 230) | 406 Not Acceptable [http://test.host/search/by_xy/4831/3242.json]
when I missed format in testing code - all works correctly,
how should I write the test?
I figured this out, actually; this is how it should be
get :by_xy, {:x => i[:x], :y => i[:y]}, :format => :json
For rails 5.1, when doing a post, I had to include the format attribute inside of my params hash
share_params = {
email: nil,
message: 'Default message.'
format: :json
}
post image_share_path(#image), params: share_params
assert_response :unprocessable_entity
If not I would get the error ActionController::UnknownFormat inside of my create controller
def create
#image = Image.new(image_params)
if #image.save
flash[:success] = 'Your image was saved successfully.'
redirect_to #image
else
respond_to do |format|
format.json do
render json: { #image.to_json },
status: :unprocessable_entity
end
end
end

Resources