【问题标题】:How do I display the value of a session variable in Ruby/Rails?如何在 Ruby/Rails 中显示会话变量的值?
【发布时间】:2020-04-25 02:14:03
【问题描述】:

首先我不知道我是否正确声明了会话变量。另外,我把它放在应用程序控制器中,因为我知道它会运行。如果有更好的地方放这个,请告诉我。期望的结果是用户在会话期间选择他们希望将所有工作保存到的团队。然后当对象被保存时,他们使用会话变量:current_team 而不是:current_user。默认情况下,在创建时将为每个新用户创建一个团队。这就是为什么我要为每个用户查询第一个团队。在会话期间,我计划让用户选择他们正在工作/贡献的团队,并且选择会一直持续到他们更改为止。

application_controller.rb

class ApplicationController < ActionController::Base
  before_action :authenticate_user!
  before_action :set_current_team

  def set_current_team
    return unless session[:current_team]
    session[:current_team] = Team.first.where(user_id: current_user).id
  end


end

index.html.erb

<p><%= session[:current_team] %></p>

输出

Processing by PagesController#index as HTML
  User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ /home/dev/.rbenv/versions/2.5.2/lib/ruby/gems/2.5.0/gems/activerecord-5.2.3/lib/active_record/log_subscriber.rb:98
  Rendering pages/index.html.erb within layouts/application
  Rendered pages/index.html.erb within layouts/application (0.5ms)
  Rendered shared/_navigation.html.erb (2.9ms)
Completed 200 OK in 172ms (Views: 168.3ms | ActiveRecord: 0.4ms)

我的模型是 Team、User 和一个联接表 Team_member。 team_member.rb

  belongs_to :user
  belongs_to :team
  belongs_to :role
end

team.rb

  has_many :team_members
  has_many :users, through: :team_members
  has_many :roles, through: :team_members
end

【问题讨论】:

    标签: ruby-on-rails ruby session-cookies


    【解决方案1】:

    我假设一个用户可以是多个团队的一部分,并且(显然)一个团队有很多用户,你的关系大概是这样的

    class User < ApplicationRecord
      has_and_belongs_to_many :teams
    end
    
    class Team < ApplicationRecord
      has_and_belongs_to_many :users
    end
    
    

    您已经在正确的方向上,但我对set_current_team 几乎没有更改,并添加了获取当前团队实例的访问器方法。

    class ApplicationController < ActionController::Base
      before_action :authenticate_user!
      before_action :set_current_team
    
      helper_method :current_team
    
      def set_current_team
        return unless session[:current_team]
        session[:current_team] = current_user.teams.first.id
      end
    
      def current_team
        @_team ||= Team.find(session[:current_team])
      end
    end
    

    current_team方法在请求过程中使用memoization技术缓存当前团队,这样如果在请求过程中多次调用current_team,它就不会再次调用数据库获取团队记录。

    我强烈推荐阅读这篇文章4 Simple Memoization Patterns in Ruby。

    还要注意set_current_team 上方的helper_method 宏,它使这个辅助方法也可用于您的视图。

    因此以下内容将适用于您的索引

    <p><%= current_team %></p>
    

    以及跨所有控制器,因为所有控制器都继承自 ApplicationController

    【讨论】:

    • 到目前为止,这似乎是最好的解决方案。但是,我将其作为

      的输出:#&lt;Team:0x00007fe5846341a8&gt; 我还应该告诉你我有一个联接表 Team_Members,但我认为这不是问题。
    • 打印对象。现在,如果teams 表中有name 字段,则可以使用current_team.name 打印当前团队的名称。同样,您可以访问团队对象的所有列/属性。
    【解决方案2】:

    拥有session[:current_team] 后,您可以将其保存到任何控制器中的变量中。例如在团队控制器中,你可以这样做:@current_team = session[:current_team]。然后在视图中可以使用@current_team。

    【讨论】:

    • 这绝对是我出错的部分原因。我没有意识到我必须将会话 cookie 值分配给一个变量。
    • 我给了你一个赞成票,在我看来,我仍然得到某种哈希输出。 #&lt;Team:0x00007fe58f47b360&gt;
    • 您在视图中使用的是什么?你在使用 吗?
    【解决方案3】:

    将set_current_team 方法更新为

    class ApplicationController < ActionController::Base
      before_action :authenticate_user!
      before_action :set_current_team
    
      # only set the session[:current_team] if it is nil (when user login)
      def set_current_team
        session[:current_team] ||= current_user.teams.first.id
      end
    
      # to access current_team
      def current_team
        @current_team ||= Team.find(session[:current_team])
      end
    end
    

    在处理请求的controller#action中将session[:current_team]设置为用户选择的团队ID

    在用户注销时将session[:current_team] 设置为nil

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-01
      • 1970-01-01
      • 2017-07-04
      • 2015-05-27
      相关资源
      最近更新 更多