Reputation: 889
Hi I have a simple rails application that has two models Equipment_Types & Tasks
Each equipment type has many tasks. When I export to csv file I would like to export the name of the equipment type, the task name and the associated schedule. Basically every thing that is displayed on equipment_type/show.html.erb
<p id="notice"><%= notice %></p>
<div class="row">
<table class="table table-bordered">
<thead>
<tr>
<th class="align-middle" rowspan="2">Equipment</th>
<th class="align-middle" rowspan="2">Task</th>
<th class="text-center" colspan="4">Frequency</th>
</tr>
<tr>
<th class="text-center">M</th>
<th class="text-center">Q</th>
<th class="text-center">B</th>
<th class="text-center">A</th>
</tr>
</thead>
<tbody>
<tr>
<% if @taskcount > 3 %>
<td class="text-center bottomtotop" rowspan="0"><%= link_to @equipment_type.name, edit_equipment_type_path(@equipment_type) %></td>
<% else %>
<td class="text-center" rowspan="0"><%= link_to @equipment_type.name, edit_equipment_type_path(@equipment_type) %></td>
<% end %>
</tr>
<% @equip_tasks.each do |task| %>
<tr>
<td><%= link_to task.name, task %></td>
<td class="text-center"><%= if task.monthly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.quarterly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.sixmonthly then 'x' else ' ' end %></td>
<td class="text-center"><%= if task.annually then 'x' else ' ' end %></td>
</tr>
<% end %>
<div class="collapse" id="collapsenewline">
</div>
</tbody>
</table>
</div>
<div class="row">
<div class="col-sm">
<%= link_to 'Add Task', new_task_path(@equipment_type), class: 'btn btn-dark' %>
</div>
<div class="col-sm">
<%= link_to 'Back', equipment_types_path, class: 'btn btn-dark' %>
</div>
<div class="col-sm">
<button class="btn btn-dark" type="button" data-toggle="collapse" data-target="#collapsedownload" aria-expanded="false" aria-controls="collapseExample">
Download
</button>
</div>
</div>
<div class="row">
<div class="col-sm">
</div>
<div class="col-sm">
</div>
<div class="col-sm">
<div class="collapse" id="collapsedownload">
<div class="card card-body">
<h3>Download File</h3>
<%= link_to "csv", equipment_types_path(format: "csv"), class: 'btn btn-dark' %>
<br>
<%= link_to "pdf", equipment_types_path(format: "pdf"), class: 'btn btn-dark' %>
<br>
<%= link_to "word", equipment_types_path(format: "word"), class: 'btn btn-dark' %>
</div>
</div>
</div>
</div>
equipment_type Model
class EquipmentType < ApplicationRecord
has_many :tasks
accepts_nested_attributes_for :tasks
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
EquipmentType.create! row.to_hash
end
end
def self.to_csv
CSV.generate do |csv|
csv << column_names
all.each do |equipmenttype|
csv << equipmenttype.attributes.values_at(*column_names)
end
end
end
end
equipment_types Controller
class EquipmentTypesController < ApplicationController
before_action :set_equipment_type, only: [:show, :edit, :update, :destroy]
before_action :set_task, only: [:show]
# GET /equipment_types
# GET /equipment_types.json
def index
@equipment_types = EquipmentType.all
respond_to do |format|
format.html
format.csv { send_data @equipment_types.to_csv }
end
end
# GET /equipment_types/1
# GET /equipment_types/1.json
def show
@equipment_type = EquipmentType.find_by(id: params[:id])
@tasks = Task.all
@equip_tasks = @equipment_type.tasks.all
@taskcount = @equip_tasks.count
respond_to do |format|
format.html
format.csv { send_data text: @equip_tasks.to_csv }
end
end
# GET /equipment_types/new
def new
@equipment_type = EquipmentType.new
end
# GET /equipment_types/1/edit
def edit
end
# POST /equipment_types
# POST /equipment_types.json
def create
@equipment_type = EquipmentType.new(equipment_type_params)
respond_to do |format|
if @equipment_type.save
format.html { redirect_to @equipment_type, notice: 'Equipment type was successfully created.' }
format.json { render :show, status: :created, location: @equipment_type }
else
format.html { render :new }
format.json { render json: @equipment_type.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /equipment_types/1
# PATCH/PUT /equipment_types/1.json
def update
respond_to do |format|
if @equipment_type.update(equipment_type_params)
format.html { redirect_to @equipment_type, notice: 'Equipment type was successfully updated.' }
format.json { render :show, status: :ok, location: @equipment_type }
else
format.html { render :edit }
format.json { render json: @equipment_type.errors, status: :unprocessable_entity }
end
end
end
def import
EquipmentType.import(params[:file])
redirect_to equipment_type_path, notice: "Equipment Type Added Successfully"
end
# DELETE /equipment_types/1
# DELETE /equipment_types/1.json
def destroy
@equipment_type.destroy
respond_to do |format|
format.html { redirect_to equipment_types_url, notice: 'Equipment type was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_equipment_type
@equipment_type = EquipmentType.find(params[:id])
end
def set_task
@task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def equipment_type_params
params.require(:equipment_type).permit(:name, task: [])
end
end
Task Model
class Task < ApplicationRecord
belongs_to :equipment_type
end
Tasks Controller
class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy]
# GET /tasks
# GET /tasks.json
def index
@tasks = Task.all
end
# GET /tasks/1
# GET /tasks/1.json
def show
end
# GET /tasks/new
def new
@task = Task.new
end
# GET /tasks/1/edit
def edit
end
# POST /tasks
# POST /tasks.json
def create
@task = Task.new(task_params)
respond_to do |format|
if @task.save
format.html { redirect_to @task, notice: 'Task was successfully created.' }
format.json { render :show, status: :created, location: @task }
else
format.html { render :new }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /tasks/1
# PATCH/PUT /tasks/1.json
def update
respond_to do |format|
if @task.update(task_params)
format.html { redirect_to @task, notice: 'Task was successfully updated.' }
format.json { render :show, status: :ok, location: @task }
else
format.html { render :edit }
format.json { render json: @task.errors, status: :unprocessable_entity }
end
end
end
# DELETE /tasks/1
# DELETE /tasks/1.json
def destroy
@task.destroy
respond_to do |format|
format.html { redirect_to tasks_url, notice: 'Task was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_task
@task = Task.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def task_params
params.require(:task).permit(:name, :monthly, :quarterly, :sixmonthly, :annually, :equipment_type_id)
end
end
Upvotes: 2
Views: 1396
Reputation: 5363
This should get you started:
You merely need to just append the attributes to the array.
Instead of,
csv << equipmenttype.attributes.values_at(*column_names)
Drop in this (or similar) (note: this is resource-intensive so you'll want to trim it down especially if you have lots of tasks)
def csv_attributes
{
tasks: self.tasks.all.map(&:attributes).map(&:values),
id: self.id
}
end
and then
csv << equipmenttype.csv_attributes
Upvotes: 1