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

时间:2015-07-28 16:28:42

标签: javascript ruby-on-rails ruby ruby-on-rails-4 model-view-controller

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('test23@example.com') 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?

3 个答案:

答案 0 :(得分:1)

这非常难看,但它有效,将您的操作代码更改为:

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

这会在客户端直接呈现js代码,并将window位置更改为预期网址(在这种情况下为root_path)。

答案 1 :(得分:1)

通过js请求重定向试试这个。

<% 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 %>

答案 2 :(得分:0)

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.