programing

레일 3: Ajax 콜에서 "redirect_to"를 하려면 어떻게 해야 합니까?

closeapi 2023. 3. 17. 21:29
반응형

레일 3: Ajax 콜에서 "redirect_to"를 하려면 어떻게 해야 합니까?

이하와 같다attempt_login메서드는 로그인 폼이 전송된 후 Ajax를 사용하여 호출됩니다.

class AccessController < ApplicationController
  [...]
  def attempt_login
    authorized_user = User.authenticate(params[:username], params[:password])

    if authorized_user
      session[:user_id] = authorized_user.id
      session[:username] = authorized_user.username
      flash[:notice] = "Hello #{authorized_user.name}."
      redirect_to(:controller => 'jobs', :action => 'index')
    else
      [...]
    end
  end
end

문제는 말이다redirect_to동작하지 않습니다.

이 문제를 어떻게 해결하시겠습니까?

결국, 나는 그냥 교체했다.

redirect_to(:controller => 'jobs', :action => 'index')

다음과 같이 입력합니다.

render :js => "window.location = '/jobs/index'"

잘 작동해요!

다음 요청에 대비하여 플래시를 보관하는 매우 쉬운 방법이 있습니다.컨트롤러에서 다음과 같은 작업을 수행합니다.

flash[:notice] = 'Your work was awesome! A unicorn is born!'
flash.keep(:notice)
render js: "window.location = '#{root_path}'"

flash.keep는 다음 요구에 대비하여 플래시를 유지합니다.그래서 언제?root_path이 렌더링되면 지정된 플래시 메시지가 표시됩니다.레일즈는 훌륭합니다:)

이게 좀 더 나은 것 같아요.

render js: "window.location.pathname='#{jobs_path}'"

앱 중 하나에서 JSON을 사용하여 리다이렉트 및 플래시 메시지 데이터를 전송합니다.다음과 같이 됩니다.

class AccessController < ApplicationController
  ...
  def attempt_login
    ...
    if authorized_user
      if request.xhr?
        render :json => {
          :location => url_for(:controller => 'jobs', :action => 'index'),
          :flash => {:notice => "Hello #{authorized_user.name}."}
        }
      else
        redirect_to(:controller => 'jobs', :action => 'index')
      end
    else
      # Render login screen with 422 error code
      render :login, :status => :unprocessable_entity
    end
  end
end

간단한 jQuery의 예는 다음과 같습니다.

$.ajax({
  ...
  type: 'json',
  success: functon(data) {
    data = $.parseJSON(data);
    if (data.location) {
      window.location.href = data.location;
    }
    if (data.flash && data.flash.notice) {
      // Maybe display flash message, etc.
    }
  },
  error: function() {
    // If login fails, sending 422 error code sends you here.
  }
})

모든 답변 중에서 가장 좋은 답변의 조합:

...
if request.xhr?
  flash[:notice] = "Hello #{authorized_user.name}."
  flash.keep(:notice) # Keep flash notice around for the redirect.
  render :js => "window.location = #{jobs_path.to_json}"
else
...
def redirect_to(options = {}, response_status = {})
  super(options, response_status)
  if request.xhr?
    # empty to prevent render duplication exception
    self.status = nil
    self.response_body = nil
    path = location
    self.location = nil

    render :js => "window.location = #{path.to_json}"
  end
end

컨트롤러 액션을 수정하고 싶지 않았기 때문에 다음과 같은 해킹을 생각해 냈습니다.

class ApplicationController < ActionController::Base
  def redirect_to options = {}, response_status = {}
    super

    if request.xhr?
      self.status        = 200
      self.response_body = "<html><body><script>window.location.replace('#{location}')</script></body></html>"
    end
  end
end

언급URL : https://stackoverflow.com/questions/5454806/rails-3-how-to-redirect-to-in-ajax-call

반응형