Nick
Nick

Reputation: 3090

Rails controller and javascript: don't give the desired redirect result

Users of my website can use a discount coupon. If this coupon entitles them to a 100% rebate, it should update some values for the user and redirect to the root with a flash message. However, the current behavior is that upon submitting the coupon/form, nothing happens on screen; i.e., the page with the form remains displayed, there's not alert message, no redirection, etc. The server log shows that there is action happening but I don't understand why on screen nothing happens. Can anyone please advice?

The form for a user to submit a promotion code:

<%= form_for @code, method: :post, url: {action: "checkcode", :controller => 'codes', format: 'js'}, remote: true do |f| %>
  <%= f.submit "Submit Code" %>
  <%= f.text_field :code, :placeholder => "Enter code" %>
  <%= some hidden_fields %>
<% end %>

This posts to the following javascript file, which sets some values and updates those values on screen.

alert('<%= @message %>');
<% if @sum %>
    $('.js-sum').val('<%= @sum%>');
    $('.js-hash').val('<%= @hash%>');
    $('.js-sum2').html('<%= number_with_precision(@sum, precision: 2) %>');
<% end %>

The controller method is as follows:

def checkcode
  code = Code.active.by_code(params[:code][:name]).first
  # ... some code that checks 'code' and accordingly sets `@sum`... this works
  if @sum && @sum == 0
    @message = "Accepted"
    @organization = Organization.friendly.find(params[:id])
    if @organization.update_attributes(promo_id: code.name,
                            promo_date: Time.zone.now,
                            exp_date: @organization.check_expiration)
      flash.now[:success] = "A confirmation email is sent to you."
      redirect_to root_path
    else
      flash.now[:danger] = "Error"
    end
  end
end

The server log:

Started POST "/checkcode.js" 
Processing by CodesController#checkcode as JS
  Parameters: {"utf8"=>"✓", "code"=>{"code"=>"fullrebate"}, "current_sum"=>"100.0", ***, "organization_id"=>"108", "commit"=>"Submit"}
  Code Load (0.9ms)  SELECT  "codes".* FROM "codes" WHERE (expiration >= '2015-07-28') AND (code = 'fullrebate')  ORDER BY "codes"."expiration" DESC LIMIT 1
  Organization Load (0.5ms)  SELECT  "organizations".* FROM "organizations" WHERE "organizations"."tag" = $1  ORDER BY "organizations"."created_at" DESC LIMIT 1  [["tag", "108"]]
  Organization Load (0.6ms)  SELECT  "organizations".* FROM "organizations" WHERE "organizations"."id" = $1  ORDER BY "organizations"."created_at" DESC LIMIT 1  [["id", 108]]
   (0.4ms)  BEGIN
  User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."organization_id" = $1  ORDER BY "users"."username" ASC  [["organization_id", 108]]
  User Exists (0.9ms)  SELECT  1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('[email protected]') AND "users"."id" != 235) LIMIT 1
   (1.0ms)  SELECT "users"."email" FROM "users"  ORDER BY "users"."username" ASC
  User Exists (1.0ms)  SELECT  1 AS one FROM "users" WHERE (LOWER("users"."username") = LOWER('test23') AND "users"."id" != 235) LIMIT 1
  Organization Exists (0.8ms)  SELECT  1 AS one FROM "organizations" WHERE (LOWER("organizations"."name") = LOWER('test23') AND "organizations"."id" != 108) LIMIT 1
  Organization Exists (0.7ms)  SELECT  1 AS one FROM "organizations" WHERE (LOWER("organizations"."tag") = LOWER('tes23') AND "organizations"."id" != 108) LIMIT 1
  SQL (0.6ms)  UPDATE "organizations" SET "expiration" = $1, "updated_at" = $2 WHERE "organizations"."id" = $3  [["expiration", "2020-07-31"], ["updated_at", "2015-07-28 16:10:38.906460"], ["id", 108]]
   (3.7ms)  COMMIT
Redirected to https://homepage.com/
Completed 302 Found in 241ms (ActiveRecord: 11.6ms)

Started GET "/" 
Processing by HomePagesController#home as JS
  Rendered shared/_header.html.erb (53.9ms)
  Rendered shared/_error_messages.html.erb (0.6ms)
  Rendered home_pages/home.html.erb within layouts/application (399.8ms)
  Rendered shared/_shim.html.erb (0.5ms)
  Rendered shared/_footer.html.erb (3.9ms)
Completed 200 OK in 3431ms (Views: 3421.5ms | ActiveRecord: 0.0ms)

So on the one hand the server log shows it is executing the controller method and redirecting, but at the same time on screen nothing happens (i.e., does not go to homepage). The line Processing by HomePagesController#home as JS strikes me as odd. Is the as JS perhaps the cause of the problem and what to do about it?

Upvotes: 0

Views: 96

Answers (3)

Athar
Athar

Reputation: 3268

for redirection through js request try this.

<% if @amount && @amount < 0.01 %> 
  $(window.location.replace("/"))
<% end %> 

alert('<%= @msg %>'); 
<% if @amount %> 
  $('.js-input-amount').val('<%= @amount%>'); 
  $('.js-input-hash').val('<%= @hash%>'); 
  $('.js-text-amount').html('<%= number_with_precision(@amount, precision: 2) %>'); 
<% end %>

Upvotes: 1

Roman Kiselenko
Roman Kiselenko

Reputation: 44360

This is very ugly, but it works, change you action code to:

def checkcode
  # some code here    
  render js: "window.location = '#{root_path}'"
  # some code here
end

This directly render js code on the client-side, and change window location to expected url(root_path in this case).

Upvotes: 1

LukeS
LukeS

Reputation: 481

You should use

 redirect_to action: :index

or

redirect_to '/'

instead of

redirect_to root_path

If it is an issue with async post you could try using something like this

respond_to do |format|
  format.js { :location => path_to_controller_method_url(argument) }
end

in your controller.

Upvotes: 0

Related Questions