编写一个包装函数,用来自不同表的数据下载csv数据

时间:2013-11-11 19:03:09

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

这是我在order.rb

中编写的csv创建函数
  def self.to_csv(column_names)
    CSV.generate do |csv|
      csv << column_names
      all.each do |order|
        csv << order.attributes.values_at(*column_names)
      end
    end
  end

我在控制器中写了以下内容,即orders控制器。

def csv_downloader
    start_date=params[:class_start_date]
    end_date=params[:class_end_date]
    if start_date.to_date<=end_date.to_date
    respond_to do |format|
      if params[:data]="orders_customs_display"
        column_names=["created_at","order_legacy_id","clip_category_id","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut"]
        format.csv { send_data Order.customs_not_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).select("created_at","order_legacy_id","clip_category_id","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut").to_csv(column_names) }
        elsif params[:data]="orders_customs_refunded"
        column_names=["created_at","order_legacy_id","performer_id","clip_category_id","duration_id","quality_id","delivery_time_id","total"]  
        format.csv { send_data Order.customs_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).select("created_at","order_legacy_id","performer_id","clip_category_id","duration_id","quality_id","delivery_time_id","total").to_csv(column_names) }
        elsif params[:data]="orders_white_label_display"
        column_names=["created_at","orderrder_legacy_id","clip_category_id","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut"]
        format.csv { send_data Order.white_label_not_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).to_csv }
        elsif params[:data]="orders_white_label_refunded"
        format.csv { send_data Order.white_label_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).to_csv }
        elsif params[:data]="orders_affiliate_display"
        format.csv { send_data Order.affiliate_not_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).to_csv }
        else
        format.csv { send_data Order.affiliate_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).to_csv }
      end
    end
    else
        redirect_to orders_path,:notice=>"Start date should be higher than end date or equal"
    end
  end

正如您所看到的那一行,使用相应的列名称选择表中所需的列,并将它们打印到csv中。

column_names=["created_at","order_legacy_id","clip_category_id","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut"]
format.csv { send_data Order.customs_not_refunded.where("created_at BETWEEN ? AND ?",start_date.to_date,end_date.to_date).select("created_at","order_legacy_id","clip_category_id","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut").to_csv(column_names) }

现在问题是我有clip_category_id,它只是一个与订单表关联的列。我希望能够访问name表中的列clip_category,然后在表中打印,而不是单独使用id。有没有办法做到这一点?


我尝试了以下

Order.customs_not_refunded.joins(:clip_category).where("created_at BETWEEN ? AND ?","1-10-2013".to_date,DateTime.now.to_date).select("created_at","order_legacy_id","name","duration_id","quality_id","delivery_time_id","clip_status","total","perf_cut","c4u_cut")

要获得以下错误:

Order Load (0.7ms)  SELECT created_at, order_legacy_id, name, duration_id, quality_id, delivery_time_id, clip_status, total, perf_cut, c4u_cut FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '2013-10-01' AND '2013-11-12') ORDER BY created_at DESC
SQLite3::SQLException: ambiguous column name: created_at: SELECT created_at, order_legacy_id, name, duration_id, quality_id, delivery_time_id, clip_status, total, perf_cut, c4u_cut FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '2013-10-01' AND '2013-11-12')  ORDER BY created_at DESC
ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: created_at: SELECT created_at, order_legacy_id, name, duration_id, quality_id, delivery_time_id, clip_status, total, perf_cut, c4u_cut FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '2013-10-01' AND '2013-11-12')  ORDER BY created_at DESC

我尝试了以下

Order.customs_not_refunded.joins(:clip_category).where("created_at BETWEEN ? AND ?","1-10-213".to_date,DateTime.now.to_date).select("orders.created_at")

得到以下

    Order Load (98.6ms)  SELECT orders.created_at FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '0213-10-01' AND '2013-11-12') ORDER BY created_at DESC
SQLite3::SQLException: ambiguous column name: created_at: SELECT orders.created_at FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '0213-10-01' AND '2013-11-12')  ORDER BY created_at DESC
ActiveRecord::StatementInvalid: SQLite3::SQLException: ambiguous column name: created_at: SELECT orders.created_at FROM "orders" INNER JOIN "clip_categories" ON "clip_categories"."id" = "orders"."clip_category_id" WHERE "orders"."payment_status" = 't' AND "orders"."refunded" = 'f' AND (created_at BETWEEN '0213-10-01' AND '2013-11-12')  ORDER BY created_at DESC

更新3

Order.customs_not_refunded.joins(:clip_category).where("orders.created_at BETWEEN ? AND ?","1-10-213".to_date,DateTime.now.to_date)

这没有错误。如何从两个表中单独获取特定的colums。说出订单中的created_at列和clip_category_id

中的name

2 个答案:

答案 0 :(得分:0)

created_at在两个表中。在你的where()调用中,使用你要过滤的那个创建前缀created_at,例如: orders.created_at或clip_categories.created_at。

答案 1 :(得分:0)

我最终使用了这个

Order.customs_not_refunded.joins(:clip_category).joins(:delivery_time).joins(:quality).joins(:duration).where("orders.created_at BETWEEN ? AND ?","1-10-213".to_date,DateTime.now.to_date).select("orders.*,clip_categories.name AS category,qualities.name AS quality,durations.time AS duration,delivery_times.duration AS delivery_time")