Rails - 会话变量不会持久

时间:2015-06-02 16:07:01

标签: ruby-on-rails ajax

我想在rails会话变量中保存侧边菜单的状态,这样如果我的用户折叠了侧边菜单,那么当视图更改时,折叠状态将保持不变。我有我的js设置,以便一个未崩溃的状态将发送" 0"通过控制器,如果侧面菜单处于折叠状态,ajax将发送" 1"通过控制器动作。如果控制器操作收到" 1",我想在我的应用程序中设置该会话变量。

我目前对相应的控制器操作有一个ajax请求,折叠的side-nav正在发送" 1"通过成功,但会话变量似乎没有持续。以下是侧面导航折叠时我在控制台中看到的内容:

CONSOLE: (当侧面导航折叠时)

Started POST "/dashboard/side_nav_state" for 10.0.2.2 at 2015-06-02 15:58:08 +0000
Processing by DashboardController#side_nav_state as */*
  Parameters: {"hide_side_nav"=>"1"}
Completed 200 OK in 2ms (Views: 0.2ms | ActiveRecord: 0.0ms)

(扩展侧导航时)

Started POST "/dashboard/side_nav_state" for 10.0.2.2 at 2015-06-02 16:02:56 +0000
Processing by DashboardController#side_nav_state as */*
  Parameters: {"hide_side_nav"=>"0"}
Completed 200 OK in 2ms (Views: 0.2ms | ActiveRecord: 0.0ms)

JavaScript的:

sendSideNav();函数实际上将1或0传递给控制器​​。如您所见,collapsedSideNav();函数发送1.如果查看sendSideNav();函数,您可以看到1传递给ajax请求中的数据键值对。

// collapsible side-nav functionality
function collapsedSideNav(){
  $('.side-nav').toggle(300);
  $('#collapse-side-nav').css('display', 'none');
  $('#expand-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 0
  }, "slow");
  $('.row').css({
    'max-width' : '98%',
    'margin-left' : '1.15rem'
  });
  sendSideNavStatus(1);
};

// expandable side-nav functionality
function expandedSideNav(){
  $('.side-nav').toggle(325);
  $('#expand-side-nav').css('display', 'none');
  $('#collapse-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 200
  }, "slow");
  $('.row').animate({
    'max-width' : '95%',
    'margin-left' : 'auto'
  });
  sendSideNavStatus(0);
};

// sends the state of the side-menu (if not default) to the controller so it can be stored in a session
// 1 for true, and 0 for false.
function sendSideNavStatus(trueOrFalse){
  $.ajax({
    url: '/dashboard/side_nav_state',
    method: 'POST',
    data: {hide_side_nav: trueOrFalse}
  });
};

// DOM Events for collapsing and expanding side-nav
$('#collapse-side-nav').click(function() {
  collapsedSideNav();
});
$('#expand-side-nav').click(function() {
  expandedSideNav();
});

路线

post 'dashboard/side_nav_state'

控制器行动

def side_nav_state
    session[:hide_side_nav] = params[:hide_side_nav] == "1" 
    render json: {success: true}
end

修改

我应该注意,所有这些都发生在我的仪表板控制器中。无论我在哪个控制器,我都希望这个会话能够持续存在。这可能吗?我知道您无法路由到应用程序控制器,这就是我为仪表板控制器设置逻辑的原因。我不确定这里的解决方案是什么。

1 个答案:

答案 0 :(得分:2)

对于其他任何最终遇到此问题并且无法找到答案的人,我终于得出了如何解决问题的结论。

我发现rails会话主要用于后端逻辑(用户身份验证,用户首选项等)。上面我的代码的问题是我的javascript在任何地方都没有收到会话变量。。会话变量设置正确并且持久化,但因为我需要会话变量对javascript采取行动,所以变量是一个有争议的点。

我可以设置一个post端点并创建第二个ajax请求。但这会产生许多额外的代码,包括另一个端点,另一个控制器动作,以及javascript。

因为Rails并没有真正提供一个让你的javascript与会话变量交互的好方法,对于这个特殊的问题我决定最好在客户端100%处理问题并创建一个浏览器cookie 。我使用了cookie.js库并相应地设置了cookie。我的最终代码最终看起来像这样:

<强> JAVASCRIPT:

$(document).ready(function(){
  Cookies.get();
  initializeSideNav();
});

// Checks the current status of the side menu
function initializeSideNav() {
  if (Cookies.get("collapsed-side-nav") === "true") {
    collapsedSideNav();
  }
}

// collapsible side-nav functionality
function collapsedSideNav(){
  $('.side-nav').toggle(300);
  $('#collapse-side-nav').css('display', 'none');
  $('#expand-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 0
  }, "slow");
  $('.row').css({
    'max-width' : '98%',
    'margin-left' : '1.15rem'
  });
  Cookies.set('collapsed-side-nav', true, {path: '/'})
  console.log(Cookies.get());
};

// expandable side-nav functionality
function expandedSideNav(){
  $('.side-nav').toggle(325);
  $('#expand-side-nav').css('display', 'none');
  $('#collapse-side-nav').css('display', 'inherit');
  $('.container').animate({
    'padding-left' : 200
  }, "slow");
  $('.row').animate({
    'max-width' : '95%',
    'margin-left' : 'auto'
  });
  Cookies.set('collapsed-side-nav', false, {path: '/'});
  console.log(Cookies.get());
};

// DOM Events for collapsing and expanding side-nav
$('#collapse-side-nav').click(function() {
  collapsedSideNav();
});
$('#expand-side-nav').click(function() {
  expandedSideNav();
});