Rails:通过调用Ajax进行重定向 [英] Rails: redirect with call to Ajax

查看:71
本文介绍了Rails:通过调用Ajax进行重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将未登录的用户直接重定向到登录窗口,这是一个引导模式窗口.

I'm trying to redirect un-logged-in users directly to a login window, which is a bootstrap modal window.

我在ApplicationController中编写了一个名为logged_in_user的方法:

I wrote a method called logged_in_user in ApplicationController:

def logged_in_user
  unless !current_user.nil?
    flash[:danger] = "Please log in"
    redirect_to root_url
  end
end

login_url路由到sessions#new,我将其定义如下:

The login_url routes to sessions#new, which I defined as below:

(sessions_controller.rb)

def new
  respond_to do |format|
    format.html
    format.js
  end
end

这是redirect_to root_url指向的视图:

  <!-- Login Window -->
  <div id="login-window" class="modal fade" role="dialog" aria-labelledby="login" aria-hidden="true"></div>

这里是new.js.erb,它在调用sessions#new时被执行:

Here is new.js.erb that gets executed when sessions#new is called:

$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");

因此,一旦sessions#new被调用,登录表单(在app/views/sessions中为_new.html.erb)将显示为弹出窗口.

Thus the login form, which is _new.html.erb in app/views/sessions, will appear as a popup window once the sessions#new is called.

除了必须将其作为JS(而不是HTML)处理.因此,我具有以下链接,该链接在_header.html.erb中并且可在所有视图中使用,以确保确实如此:

Except that it has to be processed as JS rather than HTML. So I have the following link, which is in the _header.html.erb and available across all views, to ensure this is the case:

<%= link_to "Log in", login_path, {remote: true, 'data-toggle' =>  "modal", 'data-target' => '#login-window'} %>

当单击链接时,此方法工作正常.这就是为什么我选择在logged_in_user方法中执行redirect_to root_url而不是redirect_to login_url的原因,因为后一种方法会导致缺少模板错误".

This works fine when the link is clicked. This is why I chose to do redirect_to root_url rather than redirect_to login_url in logged_in_user method as the latter approach results in "Missing Template error".

但是我真正想要的是将用户直接重定向到弹出窗口,而不是先将用户重定向到root_url,而不必单击登录"链接来输入表单. 换句话说,我需要一种通过发出Ajax请求以某种方式将用户重定向到sessions#new的方法,以便可以将sessions#new作为JS处理.

But what I really want is for users to be redirected straight to the popup window, rather than them being redirected to root_url first and having to click "Login" link to enter the form. In other words, I need a way to somehow redirect users to the sessions#new by issuing an Ajax request so that sessions#new can be processed as JS.

我尝试了以下方法来实现logged_in_user方法中所需的重定向,但均无效:

I tried the following approaches for the desired redirect within logged_in_user method, none of which worked:

render js: "window.location = <%= escape_javascript(render 'sessions/new') %>"

render js: "window.location = '/sessions/new'"

redirect_to login_url, format: "js"

任何建议将不胜感激!

推荐答案

此问题已通过修改以下文件解决:

This issue was solved by modifying the following files:

( application_controller.rb )

def logged_in_user
  unless !current_user.nil?
    session[:modal] = true
    redirect_to !request.referrer.nil? ? (request.referer + "#login-window") : "#login-window" 
  end 
end

我已经省略了flash[:danger],因为它显示在后面"的褪色中 屏幕.我添加了request.referer以确保登录弹出窗口出现在用户发出请求的位置,而不是将其重定向到root_path.我认为这对于用户体验会更好. (三元只是为了处理request.referer可以为nil的情况,在这种情况下,代码会引发错误.) session[:modal] = true后面的主题如下所述.

I've omitted flash[:danger] because it was shown "behind" the faded screen. I've added request.referer to make sure that the login popup window appears where the user has made a request, rather than redirecting them to root_path. I thought this would be better for user experience. (The ternary was just to handle the case where request.referer can be nil, in which case the code rases an error.) The motif behind session[:modal] = true is explained below.

(在 application.html.erb 底部)

<% if session[:modal] == true %>
  <script type="text/javascript">
    $(document).ready(function() {
      if(window.location.href.indexOf('#login-window') != -1) {
        $('#login-window').modal('show');
        $("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");
      }
    });
  </script>
  <% session[:modal] = false %>
<% end %>

在这里,我直接在视图模板内部使用javascript.由于出现弹出窗口的视图模板不限于一个特定的模板,因此我在application.html.erb中使用了脚本,该脚本适用于所有视图模板.上半部分的灵感来自 cruncher 的答案. (谢谢!)然后我添加了$("#login-window").html("<%= escape_javascript(render 'sessions/new') %>");以确保确实显示了登录表单(``app/views/sessions/_new.html.erb).

Here I'm using javascript directly inside the view template. Since the view template upon which the popup window appears is not limited to one particular template, I've out the script inside application.html.erb, which applies to all view templates. The first half of it was inspired by cruncher 's answer. (Thank you cruncher!) I've then added $("#login-window").html("<%= escape_javascript(render 'sessions/new') %>"); to make sure that the login form (``app/views/sessions/_new.html.erb) does appear.

现在,由于我希望仅当非登录用户尝试访问需要登录的页面时才显示登录弹出窗口,因此我继续添加session[:modal] = true来表示确实调用了logged_in_user方法,表示确实发生了上述情况.

Now, since I want the login popup window to appear only when non-logged-in users try to access pages which require login, I went ahead and added session[:modal] = true to indicate that logged_in_user method was indeed called, which means that the above situation indeed occurred.

然后,在application.html.erb内部,我可以检查<% if session[:modal] == true %>是否应显示弹出窗口.在这种情况下,将执行脚本,然后将session[:modal]的值设置为false.

Then, inside application.html.erb I can check whether the popup window should appear by <% if session[:modal] == true %>. If that's the case, then the script will be executed, after which I set the value of session[:modal] to false.

session[:modal]逻辑可能不是必需的(实际上,如果没有它,它就可以很好地工作),但是我添加了它是为了以防万一.

This session[:modal] logic may not be necessary (in fact, it worked fine without it), but I've added it just in case.

就这样:)

此外,对于那些想要通过引导程序实现此弹出窗口功能的人,这是我发现非常有用的博客:

Also, for those of you who want to implement this pop-up window functionality with bootstrap, here is a blog I've found really useful:

https://coderwall.com /p/ej0mhg/open-a-rails-form-with-twitter-bootstrap-modals

祝您编程愉快!

这篇关于Rails:通过调用Ajax进行重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆