Topic: After a successfull AJAX validation I'm not redirected where I want

As the topic say I don't understand why I'm not redirected where I want after a successfull AJAX form submission.

Let me explain step by step.
At the beginning I'm in the new:

Started GET "/pay_checks/new" for 127.0.0.1 at Thu Oct 27 10:07:15 +0200 2011
  Processing by PayChecksController#new as HTML

When I submit the form...

Started POST "/pay_checks" for 127.0.0.1 at Thu Oct 27 10:08:22 +0200 2011
  Processing by PayChecksController#create as JS

The form is processed by the create controller as JS (its' ok)
In the create action, the format.js redirect to the index view path with a parameter...

format.js { redirect_to(pay_checks_url(:contract => @contract_id), :notice => 'Pay check was successfully created.') }

And at the end of the processing I see

Redirected to http://localhost:3000/pay_checks?contract=4

It's ok... I want to go there... but this is what happens:

Started GET "/pay_checks?contract=4" for 127.0.0.1 at Thu Oct 27 10:08:22 +0200 2011
  Processing by PayChecksController#index as JS
...
Rendered pay_checks/index.html.erb within layouts/application (20.3ms)

And I'm in the new! I'm not in the index as the log is saying.
I think that the problem is that I didn't set up the format.js n the index action, what sould I put there?

Thanks to all for the help

Re: After a successfull AJAX validation I'm not redirected where I want

mmmh... I want to go to /pay_checks?contract=4 with "contract" as parameter in the url.
The log file:

Started GET "/pay_checks?id=1" for 127.0.0.1 at Thu Oct 27 18:09:24 +0200 2011
  Processing by PayChecksController#index as JS
  Parameters: {"id"=>"1"}
  [1m[36mUser Load (0.2ms)[0m  [1mSELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1[0m
  [1m[35mPayCheck Load (0.3ms)[0m  SELECT "pay_checks".* FROM "pay_checks" WHERE (contract_id = NULL) ORDER BY year
Rendered pay_checks/index.html.erb within layouts/application (16.0ms)
Completed 200 OK in 54ms (Views: 27.8ms | ActiveRecord: 2.2ms)

Is right, but the page is not rendered.
If i "turn off" the :remote => true I get the correct behaviour with this redirect:

format.html { redirect_to(pay_checks_url(:contract => @contract_id), :notice => 'Pay check was successfully created.') }

It seems that the page is not rendered, and the JS console gives no help...

Re: After a successfull AJAX validation I'm not redirected where I want

Well, one clue

GET /pay_checks?id=1

Normally you'd have

GET /pay_checks

which would get you the index

or

GET /pay_checks/1

which would run the show action of pay_check with id = 1

but

GET /pay_checks?id=1

is pay_check index action, with a argument id=1,  I don't think that's what you want, is it?

Last edited by BradHodges (2011-10-27 12:37:43)

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: After a successfull AJAX validation I'm not redirected where I want

BradHodges wrote:

is pay_check index action, with a argument id=1,  I don't think that's what you want, is it?

Sorry, I pasted the wrong log, not "id" but "contract"

Started GET "/pay_checks?contract=1" for 127.0.0.1 at Thu Oct 27 21:46:09 +0200 2011
  Processing by PayChecksController#index as JS
  Parameters: {"contract"=>"1"}
  User Load (0.2ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  PayCheck Load (0.6ms)  SELECT "pay_checks".* FROM "pay_checks" WHERE (contract_id = '1') ORDER BY year
Rendered pay_checks/index.html.erb within layouts/application (21.2ms)
Completed 200 OK in 52ms (Views: 27.5ms | ActiveRecord: 0.7ms)

In the index action I want to get the the pay_checks with a foreign key for the contract.

def index
@pay_checks = PayCheck.all(:conditions => ['contract_id = ?', params[:contract]])
[...]

Do you know a better way?

Re: After a successfull AJAX validation I'm not redirected where I want

What is the relationship between PayChecks and Contracts?

Normally you'd do something like

class PayCheck < ActiveRecord::Base
  belongs_to :contract
end
class Contract < ActiveRecord::Base
  has_many :pay_checks
end

If it were me,  I'd show all paychecks for a particular contract in the show action of the contracts_controller:

app/controllers/contract_controller.rb:

def show
  @pay_checks = Contract.find(params[:id]).pay_checks
end

Last edited by BradHodges (2011-10-27 16:18:56)

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: After a successfull AJAX validation I'm not redirected where I want

BradHodges wrote:

What is the relationship between PayChecks and Contracts?

Normally you'd do something like

class PayCheck < ActiveRecord::Base
  belongs_to :contract
end
class Contract < ActiveRecord::Base
  has_many :pay_checks
end

Yes, it is my case.

BradHodges wrote:

If it were me,  I'd show all paychecks for a particular contract in the show action of the contracts_controller:

app/controllers/contract_controller.rb:

def show
  @pay_checks = Contract.find(params[:id]).pay_checks
end

In this case, you would have the management of the paycheck in the show of the contracts, and you should come back (after a pay_check insert ) to /contract/1 ...
Good idea, maybe next time smile

At the moment I still have the problem.
Any other suggestion?

Re: After a successfull AJAX validation I'm not redirected where I want

I think you should post the entire pay_checks_controller.rb

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: After a successfull AJAX validation I'm not redirected where I want

Here it is

require 'builder'

class PayChecksController < ApplicationController
  # GET /pay_checks
  # GET /pay_checks.xml
  def index
    #@pay_checks = PayCheck.all
    
    session[:contract_id] = params[:contract]
    @contract_id = session[:contract_id]
    @customer_id = session[:customer_id]
    
    # Prelevo i pay_checks relativi al contratto:
    @pay_checks = PayCheck.all(:conditions => ['contract_id = ?', @contract_id]) 

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @pay_checks }
    end
  end

  # GET /pay_checks/1
  # GET /pay_checks/1.xml
  def show
    @contract_id = session[:contract_id]
        
    @pay_check = PayCheck.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @pay_check }
    end
  end

  # GET /pay_checks/new
  # GET /pay_checks/new.xml
  def new
    @pay_check = PayCheck.new
    @contract_id  = session[:contract_id]
  
    # Recupero gli anni validi per la busta paga
    @valid_years = PayCheck.get_valid_years
    
    # Recupero se va aggiunta la tredicesima
    contract = Contract.find(@contract_id)
    
    if contract.monthly_thirteenth == '1' then
      # Calcolo la tredicesima
      @pay_check.thirteenth_instalment = 40.00 # Va poi calcolato il valore vero
    else
      @pay_check.thirteenth_instalment = 0.0
    end

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @pay_check }
    end
  end

  # GET /pay_checks/1/edit
  def edit
    @pay_check = PayCheck.find(params[:id])
  end

  # POST /pay_checks
  # POST /pay_checks.xml
  def create
    # Devo estrarre i valori degli anni anche qui perchè in caso di errore il form viene ripresentato senza "passare" dalla new 
    # Recupero gli anni validi per la busta paga
    @valid_years = PayCheck.get_valid_years

    @contract_id =  params[:pay_check][:contract_id]
    
    @pay_check = PayCheck.new(params[:pay_check])
   
    respond_to do |format|
      if @pay_check.save
      
        # Salvo i permessi
        unless params[:afford].nil? then
              
          # Passo in rassegna tutti i permessi
          params[:afford].each do |key, value|
          #logger.debug("--> #{value[:description]}")
        
            if (value[:paid] == 'true') then
              paid = "1"
            else
              paid = "0"
            end
            
            @afford = Afford.new(:description => value[:description], :hours => value[:hours], :paid => paid, :pay_check_id => @pay_check.id )
            
            unless @afford.save 
              logger.error("Errore")
            end
          end       
        end
    
        # Una volta che il contratto viene salvato aggiorno le info anche sul contratto
        PayCheck.update_contract(@contract_id, params[:pay_check][:advance_tfr])
        
         format.html { redirect_to(pay_checks_url(:contract => @contract_id), :notice => 'Pay check was successfully created.') }
         format.js { redirect_to(pay_checks_url(:contract => @contract_id), :notice => 'Pay check was successfully created.') }
         format.xml  { render :xml => @pay_check, :status => :created, :location => @pay_check }
      else
        #format.html { render :action => "new" }
        format.html { flash.now[:error] = 'Error Saving';  render :action => "new" }
        
        format.js {
          xm = Builder::XmlMarkup.new

           @pay_check.errors.full_messages.each do |msg|
             xm.span {
                 xm << msg
                 xm.br
             }
           end
           
          render(:js => xm.target!)
        }
        format.xml  { render :xml => @pay_check.errors, :status => :unprocessable_entity }  
       end
    end
  end

  # PUT /pay_checks/1
  # PUT /pay_checks/1.xml
#   def update
# Not necessary   
#   end

  # DELETE /pay_checks/1
  # DELETE /pay_checks/1.xml
  def destroy
    @contract_id = session[:contract_id]

    @pay_check = PayCheck.find(params[:id])
    @pay_check.destroy

    respond_to do |format|
      format.html { redirect_to(pay_checks_url(:contract => @contract_id)) }
      format.xml  { head :ok }
    end
  end  
end

Re: After a successfull AJAX validation I'm not redirected where I want

are you using views/layouts/application.html.erb?

are there ANY layouts in that directory?

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: After a successfull AJAX validation I'm not redirected where I want

I'm using a "personal" layout for the pay_check views, in layouts there are:

application.html.erb    pay_check.html.erb    sessions.html.erb

I'm using a different layout because it is the cleanest way I found to select wich JS to load.

Re: After a successfull AJAX validation I'm not redirected where I want

perhaps you have to FORCE the layout!

         format.js { redirect_to(pay_checks_url(:contract => @contract_id), :layout=>'pay_check', :notice => 'Pay check was successfully created.') }
Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.

Re: After a successfull AJAX validation I'm not redirected where I want

nope.
At the moment I'm doing it by JS using th window.location.href .

Re: After a successfull AJAX validation I'm not redirected where I want

This is what confuses me,  in your log is says this:

Rendered pay_checks/index.html.erb within layouts/application (20.3ms)

But if you have a a pay_checks specific layout,  it should say:

Rendered pay_checks/index.html.erb within layouts/pay_checks (20.3ms)

BTW,  what version of Rails are you using again?

I've read some other posts that imply there were some bugs or problems with layout and render_to,  but they seemed to have been corrected by 3.1.

It's a shame this isn't working as it should,  you really shouldn't need to subvert Rails to get something this straight forward to work :<

Joe got a job, on the day shift, at the Utility Muffin Research Kitchen, arrogantly twisting the sterile canvas snout of a fully charged icing anointment utensil.