Rails分配会话变量

时间:2014-12-18 21:41:50

标签: ruby-on-rails

嗨,我在过去的8个月里一直在攻击Rails,所以不要真正了解很多事情。我已经看到并使用了设置current_user等的辅助方法,现在我正在尝试复制类似的东西。

我正在尝试为用户所在的当前公司设置应用程序控制器中的全局值。我知道我做错了但我无法弄清楚如何解决它,即使我'正确地接近它。我想要它,以便当用户点击公司时,全局变量被设置为他们所在公司的id。然后在任何其他子模型中,如果我想要关于公司的信息,我使用全局变量来检索具有该id的公司对象。

导致问题的代码位于 application.html.erb

中的导航栏中
<li><%= link_to "Company", company_path, :method => :get %></li>

这在我使用公司控制器等时有效。但是当我尝试使用任何其他控制器时,我收到了错误

  

Employeers中的ActionController :: UrlGenerationError #index

No route matches {:action=>"show", :controller=>"companies"} missing required keys: [:id] 

据我所知,这意味着它无法呈现网址,因为没有传递公司ID参数?

我试图破解我在另一个项目中使用的辅助方法(用于获取current_user),但已经意识到它使用会话来提取user.id以返回用户对象。这是我在 application_controller.rb

中对helper方法的尝试
def current_company
  @company = Company.find_by_id(params[:id])
end

我无法从会话中获取当前公司,因此除非将公司ID作为参数传递,否则上述方法无效。

我考虑过在每个子模型方法上传递公司ID,但是

  1. 我不是100%确定如何做到这一点
  2. 听起来效率不高
  3. 所以我的问题是我正确接近这个吗?这样做的最佳方式是什么?我是否可以创建一个辅助方法来存储全局公司id变量,该变量在用户访问公司后设置,然后可以被其他模型检索?

    我可能没有解释得太清楚,如果您需要澄清或更多信息,请告诉我。谢谢你的期待。

      

    编辑1

    做出Ruby Racer建议的更改,现在我已经:

      

    application.html.erb

     <%unless current_page?(root_path)||current_page?(companies_path)||current_company.nil? %>
    
       <li><%= link_to "Company", company_path, :method => :get %></li>
    

    这不显示导航栏中的链接,我认为因为current_company为nil(除非在添加current_company.nil之前声明正常,否则其他两个?

    我在

    中设置current_company
      

    companies_controller.rb

    before_action :set_company, only: [:show, :edit, :update, :destroy, :company_home]
    
    def company_home
      current_company = @company
      respond_with(@company)
    end
    
      

    application_controller.rb

    def current_company=(company)
      session[:current_company] = company.id
      puts "The current_company has been assigned"
      puts params.inspect
    end
    
    def current_company
      @company = Company.find_by_id(session[:current_company])
      puts "The current_company helper has been called"
      puts @company
      puts params.inspect
    end
    

    我做错了吗?

      

    编辑2

    我不知道为什么这不起作用。完成上述编辑后,似乎session[:company_id]未被分配,因此current_company辅助方法返回nil。我已经尝试打印会话参数puts session.inspect,但找不到任何company_id信息。任何人都知道为什么不分配价值?

      

    编辑3

    不能为我的生活弄清楚出了什么问题。我尝试了多项操作,包括将current_company = @company移动到 set_company 中的companies_controller.rb方法,现在看起来像这样:

    def company_home
      puts "Test the current company"
      puts "#{@company.id} #{@company.name}"
      puts params.inspect
    end
    
     private
      def set_company
        @company = Company.find_by_id(params[:id])
        if @company.nil?||current_user.organisation_id != @company.organisation.id
        flash[:alert] = "Stop poking around you nosey parker"
        redirect_to root_path
        else
        current_company = @company
        end      
      end
    

    company_home方法被赋予了一个公司对象(我可以在下面的控制台输出中看到这一点),但current_company赋值没有发生。这是控制台输出以供参考

    Started GET "/company_home/1" for 80.55.210.105 at 2014-12-19 10:26:49 +0000                                                                                                      
    Processing by CompaniesController#company_home as HTML                                                                                                                            
      Parameters: {"authenticity_token"=>"gfdhjfgjhoFFHGHGFHJGhjkdgkhjgdjhHGLKJGJHpDQs6yNjONwSyTrdgjhgdjgjf=", "id"=>"1"}                                                                                   
      User Load (0.5ms)  SELECT  "users".* FROM "users"  WHERE "users"."id" = 6  ORDER BY "users"."id" ASC LIMIT 1                                                                    
      Company Load (0.3ms)  SELECT  "companies".* FROM "companies"  WHERE "companies"."id" = 1 LIMIT 1                                                                                
      Organisation Load (0.3ms)  SELECT  "organisations".* FROM "organisations"  WHERE "organisations"."id" = $1 LIMIT 1  [["id", 6]]                                                 
    Test the current company                                                                                                                                                          
    1 Cine                                                                                                                                                                            
    {"_method"=>"get", "authenticity_token"=>"gfdhjfgjhoFFHGHGFHJGhjkdgkhjgdjhHGLKJGJHpDQs6yNjONwSyTrdgjhgdjgjf=", "controller"=>"companies", "action"=>"company_home", "id"=>"1"}                          
      Rendered companies/company_home.html.erb within layouts/application (0.1ms)                                                                                                     
      Company Load (0.6ms)  SELECT  "companies".* FROM "companies"  WHERE "companies"."id" IS NULL LIMIT 1                                                                            
    The current_company helper has been called                                                                                                                                        
    
    {"_method"=>"get", "authenticity_token"=>"gfdhjfgjhoFFHGHGFHJGhjkdgkhjgdjhHGLKJGJHpDQs6yNjONwSyTrdgjhgdjgjf=", "controller"=>"companies", "action"=>"company_home", "id"=>"1"}                          
      CACHE (0.0ms)  SELECT  "organisations".* FROM "organisations"  WHERE "organisations"."id" = $1 LIMIT 1  [["id", 6]]                                                             
    Completed 200 OK in 280ms (Views: 274.0ms | ActiveRecord: 1.7ms)
    

    如上所述,在The current_company helper has been called行下,有一个空行,其中puts @company应该输出一些内容。这意味着current_company方法没有返回任何内容。

    此外,在companies_controller的company_home方法中,如果我将puts "#{@company.id} #{@company.name}"更改为puts "#{current_company.id} #{current_company.name}",则会引发错误。

    有谁知道为什么def current_company=(company)没有分配会话参数?感谢

      

    最终修改

    我不知道为什么,但看起来问题与此有关:

    def current_company=(company)
      session[:current_company] = company.id
      puts "The current_company has been assigned"
      puts params.inspect
    end
    

    看起来好像从未被调用过。我不明白为什么我之前从未使用过这样的东西。

    我会在答案中提出修正案。

2 个答案:

答案 0 :(得分:3)

好的,你需要做两件事。

首先,您需要将company.id分配给会话变量

def current_company=(company)
    session[:company_id]=company.id
end

其次,current_company的helper方法如下:

def current_company
    Company.find_by_id(session[:company_id])
end

如果没有session[:company_id]或者它对应于没有公司,则可以为零。没关系......

接下来,如果您使用/companies作为索引和show动作,则不太可能在没有ID的情况下使其工作。

现在,为你的第一个任务。设置变量:

控制器:companies_controller.rb

def show
    # assuming you have a before_action, something like set_company, no need to redo it
    current_company=@company # this will set the session variable
end

如果您希望导航栏指向current_company,则需要写入:

<% unless current_company.nil? %>
    <li><%= link_to "Company", current_company, :method => :get %></li>
<% end %>

如果没有现任公司,我不知道你想做什么,所以我就把它留下来。

答案 1 :(得分:0)

我没有使用辅助方法来分配值或搜索公司,而是在set_company中的companies_controller.rb方法中分配了一个会话变量。然后可以在应用程序

周围访问它
  

<强> companies_controller.rb

 private
    def set_company
       @company = Company.find_by_id(params[:id])

       if @company.nil?||current_user.organisation_id != @company.organisation.id
          redirect_to root_path
       else
          session[:current_company] = @company
          current_company = @company
       end      
    end