2016-12-10 12 views
0

我一直在关注CSV/Excel导出这Railscast,但我有关于关联逻辑的一点问题。Rails 5 - 导出到XL/CSV,但通过关联

CSV混乱/发行

在我Collection Model我有

class Collection < ApplicationRecord 
    belongs_to :user 
    has_many :card_collections 
    has_many :cards, through: :card_collections 

    def self.to_csv 
    attributes = %w{name} 

    CSV.generate(headers: true) do |csv| 
     csv << attributes 

     all.each do |collection| 
     csv << attributes.map{ |attr| collection.send(attr) } 
     end 
    end 
    end 

    # validates :user_id, presence: true 
end 

CSV导出

name 
Demo 2 
HEHHEHEEHHE 

名称是列名 演示2是第一个集合 HEHHEHEE HHE是第二个收集

我需要更多的信息,但一旦我得到'一个'参数,我可以从那里去。但是这不起作用.'name'将返回所有集合的名称,这不完全是我想要的,但我也试图获取关于集合中'卡'的信息(引用cards_collection ) 给你一个例子 - 在控制台我会输入: c = Collection.last c.cards.first.name我会得到第一个名片。 我不确定我是否应该在Card_collections控制器,Cards控制器或什么中制作self.to_csv功能。我发现了很多关于通过协会CSV但没有类似问题,这使我的解决方案

Excel的混乱

<?xml version="1.0"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:html="http://www.w3.org/TR/REC-html40"> 
    <Worksheet ss:Name="Card Collection"> 
    <Table> 
     <Row> 
     <Cell><Data ss:Type="String">Name</Data></Cell> 
     <Cell><Data ss:Type="String">Text</Data></Cell> 
     <Cell><Data ss:Type="String">Set</Data></Cell> 
     </Row> 
    <% @collection.card_collections.each do |collection| %> 
     <Row> 
     <Cell><Data ss:Type="String"><%= collection.card.name %></Data></Cell> 
     <Cell><Data ss:Type="String"><%= collection.card.text %></Data></Cell> 
     <Cell><Data ss:Type="String"><%= collection.card.set %></Data></Cell> 
     </Row> 
    <% end %> 
    </Table> 
    </Worksheet> 
</Workbook> 

是一个示例脚本 - 我确实有这个包裹在一个'每个',因为如果他们选择Excel,我会让他们每个'集合'获得一张。

为了让你的关系的想法,我Collection View样子 -

<p id="notice"><%= notice %></p> 
<div class="center"><%= @collection.name %></div><br /> 
<div class="center">Made By: 
<strong> 
    <% if @collection.public %> 
    <%= link_to @collection.user.name, {:controller => "users", :action => "show", :id => @collection.user.id} %><br /> 
    <% else %> 
    Anonymous<br /> 
    <% end %> 
</strong> 
Total Cards: <%= @collection.card_collections.sum(:card_counts) %> 
Distinct Cards: <%= @collection.card_collections.count %> <br /> 
</div> 
    <% @collection.card_collections.in_groups_of(3, false).each do |group| %> 
    <div class='row'> 
    <% group.each do |card| %> 
     <div class='col-sm-6 col-md-4'> 
     <%= image_tag(card.card.image_url, class: "img-responsive") %> 
     <h3> 
      <%= link_to card.card.name, {:controller => "cards", :action => "show", :id => card.card.id }%> 
     </h3> 
     <div><%= card_text_swap(card.card.text) %></div> 
     <div><span class='cardLabel'>Set</span>: <i class="ss ss-<%= card.card.set.downcase %> ss-3x ss-<%= card.card.rarity.downcase %>"></i> 
       <span class="setName"><%= card.card.setName %></span> 
     </div> 
     <div>Total in Collection: <%= card.card_counts %></div> 
     </div> 
    <% end %> 
    </div> 
    <% end %> 


<%= link_to 'Edit', edit_collection_path(@collection) %> | 
<%= link_to 'Back', collections_path %> 

我在制作视图中最初挣扎,但终于得到了它的工作,我试图用同样的逻辑在Excel导出中,但它不能正确呈现。 (立即无错误,所以我认为这可能是我的失败。)

附加信息所有这些都存储在ActiveDirectory中,并呈现给当前的视图。不确定我应该提供哪些其他信息。

新的Excel发行

Collections_Controller

def show 
    @collection = Collection.find(params[:id]) 
    respond_to do |format| 
     format.html 
     format.csv { render text: @collection.to_csv } 
     format.xls { send_data @collection.to_csv(col_sep: "\t") } 
    end 
    end 

查看

<%= link_to "CSV", collection_path(format: "csv") %> | 
    <%= link_to "Excel", collection_path(format: "xls") %> 

CSV现在工作 - Excel中是没有的。

错误提供:

ArgumentError in CollectionsController#show 
wrong number of arguments (given 1, expected 0) 
+0

你想获得什么CSV文件? –

+0

@ZaurAmikishiyev一个基本的信息量将是 CardName和CardSet 'c.card_collections.first.card.name'和'c.card_collections.first.card.set'是我如何在Rails控制台中分别得到的。 'Collection View'显示我如何将它称为 – DNorthrup

+0

您需要将collection_id传递给collection_path,并且您只传递格式 –

回答

1

“DEF self.to_csv” 定义了一类方法。如果你想列出给定集合的卡片,你需要定义和调用(在集合控制器的show方法中)一个实例方法。

所以我改变了你的to_csv以下列方式:

def to_csv 
    attributes = %w{name} 

    CSV.generate(headers: true) do |csv| 
    csv << attributes 
    cards.each do |card| 
     csv << attributes.map{ |attr| card.send(attr) } 
    end 
    end 
end 

这是怎么to_csv在你的控制器拨打:

class CollectionsController < ApplicationController 
    def show 
    @collection = Collection.find(params[:id]) 
    respond_to do |format| 
     format.html 
     format.csv { render text: @collection.to_csv } 
    end 
    end 
end 

为Excel:

<?xml version="1.0"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    xmlns:x="urn:schemas-microsoft-com:office:excel" 
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:html="http://www.w3.org/TR/REC-html40"> 
    <Worksheet ss:Name="Card Collection"> 
    <Table> 
     <Row> 
     <Cell><Data ss:Type="String">Name</Data></Cell> 
     <Cell><Data ss:Type="String">Text</Data></Cell> 
     <Cell><Data ss:Type="String">Set</Data></Cell> 
     </Row> 
    <% @collection.cards.each do |card| %> 
     <Row> 
     <Cell><Data ss:Type="String"><%= card.name %></Data></Cell> 
     <Cell><Data ss:Type="String"><%= card.text %></Data></Cell> 
     <Cell><Data ss:Type="String"><%= card.set %></Data></Cell> 
     </Row> 
    <% end %> 
    </Table> 
    </Worksheet> 
</Workbook> 

而且一般当你想访问指定@collection的卡时,只需使用cards关系和你在访问指定卡的属性时不需要额外的.card

+0

无视 - 我想这只是缓存。它现在工作完美。非常感谢你的帮助! – DNorthrup