嗨,我在过去的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,但是
所以我的问题是我正确接近这个吗?这样做的最佳方式是什么?我是否可以创建一个辅助方法来存储全局公司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_companycompanies_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
看起来好像从未被调用过。我不明白为什么我之前从未使用过这样的东西。
我会在答案中提出修正案。
答案 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