我正在使用设计来验证用户身份。我希望他们能够在不登录的情况下查看页面,但如果他们希望下载csv数据,他们必须登录。以下是我如何设置csv下载部分
respond_to do |format|
format.html{
render :layout => 'indices_show'
}
format.csv{
export_to_csv(idxp)
}
end
这是export_to_csv函数
def export_to_csv(idxf)
cash = params[:cash]
@title = get_title(@index)
if (cash =='1')
navs = @index.navsc.from(idxf)
r = @index.returnsc.from(idxf)
else
navs = @index.navs.from(idxf)
r = @index.returns.from(idxf)
end
dates = @index.dates.from(idxf)
csv_string = CSV.generate do |csv|
csv << [@title]
csv << ["Date", "Return", "NAV"]
dates.each_with_index do |d, i|
csv << [d,r[i],navs[i]]
end
end
send_data csv_string,
:type => 'text/csv; charset=iso-8859-1; header=present',
:disposition => "attachment; filename ="+ @title +".csv"
end
在这个控制器的顶部,我有,
before_action :authenticate_user!, only:[:export_to_csv]
但它没有做任何事情,因为用户仍然可以在没有登录的情况下下载数据。我已经找到了一个半合作的方法,
respond_to do |format|
format.html{
render :layout => 'indices_show'
}
format.csv{
if (user_signed_in?)
export_to_csv(idxp)
else
redirect_to new_user_session_path
end
}
end
这里的问题是,一旦用户登录,它就会重定向到主页。有没有这样的方式,当用户点击下载按钮时,他们被迫登录,登录后,他们被重定向回该页面并下载数据?感谢
答案 0 :(得分:1)
before_action
无效,因为export_to_csv
不是被称为操作的方法 - 通常是您的路由映射到的方法 - 也就是您{{1}的方法代码在里面。当然,您可以将方法拆分为两个单独的方法,一个用于html,一个用于csv,然后为csv设置respond_to
。这可能不太好,特别是如果它只是两种不同的查看格式相同的数据。如果它们的观点不是很相似,那么将它们分开也许是合适的。这取决于你的应用程序。
另一个选择是使用您的第二种方法,但修改它。在before_action
之前,请尝试插入redirect_to new_user_session_path
,或者传递store_location_for(:user, request.request_uri)
。请参阅此处了解文档/代码:
https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/store_location.rb#L26
您可以看到,如果存储的位置存在,则优先使用根路径:
https://github.com/plataformatec/devise/blob/master/lib/devise/controllers/helpers.rb#L143
请注意,request.original_url
似乎是最近设计的补充。我实际上使用的是3.1.x并且似乎没有定义 - 您必须直接设置store_location_for
会话变量,因为这是在3.1.x中登录时检查的内容。
答案 1 :(得分:1)
正如Tim所说,export_to_csv
不是before_action
过滤的方法。它是基于顶部的控制器操作方法触发操作,并且由于您试图将访问限制降低,因此它已经让用户通过。
我不确定你使用的动作名称是什么,所以我假设它是show
。
您可以为before_action
行提供可能限制您所希望的条件。
before_action :authenticate_user!, only: [:show], if: proc { request.csv? }