在csv下载上的rails before_action

时间:2014-03-13 17:18:38

标签: csv ruby-on-rails-4 devise

我正在使用设计来验证用户身份。我希望他们能够在不登录的情况下查看页面,但如果他们希望下载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

这里的问题是,一旦用户登录,它就会重定向到主页。有没有这样的方式,当用户点击下载按钮时,他们被迫登录,登录后,他们被重定向回该页面并下载数据?感谢

2 个答案:

答案 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? }