CSV下载对象而不是实际值Rails

时间:2013-12-22 23:26:16

标签: ruby-on-rails ruby csv routes

我不太确定在我的游戏模型中尝试允许csv下载时我忽略了什么,而且我有点迷失。

在个人资料展示页面上,我会渲染一个与该用户相关的游戏列表的索引,即他们的游戏时间表。

配置文件控制器 -

def show
 @user = User.find_by_profile_name(params[:id])

 if @user
   @listings = @user.listings
   @games = @user.games
   respond_to do |format|
     format.html
     format.csv {send_data @games.to_csv}
   end
   return

   render action: :show
 else
    render file: "public/404", status: 404, formats: [:html]
 end
end

然后在game.rb我定义方法to_csv

def self.to_csv
  CSV.generate do |csv|
    csv << column_names
    all.each do |item|
      csv << item.attributes.values_at(*column_name)
    end
  end
end

在个人资料显示页面上下载预期的csv游戏时间表

<%= link_to "Download my Schedule", profile_path(format: 'csv')%>

我相信这可能是我的问题所在,但这并不能解释我在我的csv中得到的只是一个游戏对象

file- csv-game-object

这是我的routes.rb

  resources :games

  match 'friendships/:friend_id' => 'user_friendships#new', :as => :new_friendship
  match 'dashboard' => 'dashboard#show', :as => :dashboard

  root to: "profiles#index"

  get '/players', to: 'profiles#index', as:'players'
  get '/players', to: 'profiles#index', as:'users'
  get '/:id', to: "profiles#show", as: 'profile'

文件的格式应为列名(位置,对手,时间等)作为标题行,以及相应的行,以及与用户关联的每个实例的相应值。

2 个答案:

答案 0 :(得分:4)

我认为游戏中的to_csv方法应该重新声明为 -

  1. 传入需要转换的游戏阵列。
  2. 传递给values_at的参数为column_names而不是column_name

    def self.to_csv(games)
      CSV.generate do |csv|
        csv << column_names
        games.each do |item|
          csv << item.attributes.values_at(*column_names)
        end
      end
    end
    
  3. 并且在控制器中,代码应为:

    def show
     @user = User.find_by_profile_name(params[:id])
    
     if @user
       @listings = @user.listings
       @games = @user.games
       respond_to do |format|
         format.html
         format.csv {send_data Game.to_csv(@games)}
       end
       return
    
       render action: :show
     else
        render file: "public/404", status: 404, formats: [:html]
     end
    end
    

    否则,无论您使用哪个用户,都将输出所有游戏。

答案 1 :(得分:1)

尽管中正的答案没有错,但让我详细说明一下。

语法Game.to_csv(@games)违背了Ruby的/ Rails面向对象的方法。

由于您的案例中的CSV生成代码完全独立于模型(您不对列名称做任何假设等),您可以为此方法提供任何模型数组,即Game.to_csv(@shampoos)仍可使用但读得不好。

由于Rails scopes the all method根据附加到ActiveRelation对象的条件,在类方法中使用它不会导致所有游戏的输出。

假设您至少使用Rails 3.0,行@games = @user.games将为您提供一个ActiveRelation对象,而不是一个数组,这意味着您可以调用@games.to_csv(或使其更清晰@user.games.to_csv)直接读取它是什么,即将属于用户的游戏列表转换为CSV。

哦,我想这只是测试代码,但return不应该存在。 render语句应该进入format.html的块。