我如何干涸代码以从我的动作控制器和 rails 5 中的应用程序记录中导出不同的 CSV?
How can I dry up code to export different CSVs from my action controller and application record in rails 5?
我有一个应用程序,其唯一目的是播种数据文件并将数据添加到用户压缩和导出的不同 CSV 文件中。我的应用程序控制器充满了看起来像这样的行:
def export_tips
@appointments = Appointment.order('service_id')
send_data @appointments.to_csv_tips, filename: 'tips.csv'
end
def export_ticketpayments
@appointments = Appointment.order('service_id')
send_data @appointments.to_csv_ticketpayments, filename: 'ticketspaymentitems.csv'
end
def export_batchmanifest
@batchmanifests = Batchmanifest.all
send_data @batchmanifests.to_csv_batchmanifest, filename: "batch_manifest-#{Date.today}.csv"
end
def export_pets
@clients = Client.all
send_data @clients.to_csv_pets, filename: 'pets.csv'
end
def export_clients
@clients = Client.all
send_data @clients.to_csv_clients, filename: 'clients.csv'
end
我在应用程序控制器中有它,因为我在多个不同的领域使用它,包括创建单个 CSV 导出和创建内部有多个 zip 和 CSV 的复杂 zip 文件。
我尝试清理代码的一些事情包括:
- 这个的不同变量:
def csv_export(模型,文件名)
@model.pluralize = (model.titleize).all
send_data @model.pluralize.filename, 文件名: 文件名
结束
- 每个都在自己的控制器中(无法从不同的视图和其他控制器轻松访问它们)
- 我也想弄清楚如何创建自己的模块,但无法做到。
我的申请记录同样糟糕,重复的行只是为了导出 CSV:
def self.to_csv_appointments
attributes = %w[appointment_id location_id employee_id client_id child_id notes
has_specific_employee start_time end_time]
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
def self.to_csv_appointmentservices
attributes = %w[appointment_id service_id price duration]
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
def self.to_csv_tickets
attributes = %w[ticket_id location_id client_id ticket_status employee_id
employee_id start_time]
headers = %w[ticket_id location_id client_id status employee_id
closed_by_employee_id closed_at]
CSV.generate(headers: true) do |csv|
csv << headers
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
对于应用程序记录,我尝试了与应用程序控制器列出的类似方法,但无济于事。同样,我使用应用程序记录中的代码而不是单个模型文件中的代码,因为我需要在网站的多个部分访问这些代码。
来自应用程序控制器的代码主要用于视图文件上的静态控制器和按钮。我需要能够创建文件集,如下所列,但也允许用户仅导出一个 CSV。
从静态控制器构建 zip 文件的示例:
def create_appointments_zip
file_stream = Zip::OutputStream.write_buffer do |zip|
@appointments = Appointment.order('service_id')
zip.put_next_entry "appointment_manifest.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/appointment_manifest.csv")
zip.put_next_entry "appointments.csv"; zip << @appointments.to_csv_appointments
zip.put_next_entry "appointment_services.csv"; zip << @appointments.to_csv_appointmentservices
zip.put_next_entry "appointment_statuses.csv"; zip << @appointments.to_csv_appointmentstatuses
end
file_stream.rewind
File.open("#{Rails.root}/app/assets/csvs/appointments.zip", 'wb') do |file|
file.write(file_stream.read)
end
end
def export_salonset
create_appointments_zip
create_tickets_zip
create_inventory_zip
create_memberships_zip
file_stream = Zip::OutputStream.write_buffer do |zip|
@saloncategories = Saloncategory.all
@salonservices = Salonservice.all
@clients = Client.all
@locations = Location.all
@salonpricings = Salonpricing.all
@staffs = Staff.order("location_id")
zip.put_next_entry "batch_manifest.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/batch_manifest_simple_salon.csv")
zip.put_next_entry "categories.csv"; zip << @saloncategories.to_csv_saloncategories
zip.put_next_entry "clients.csv"; zip << @clients.to_csv_clients
zip.put_next_entry "employees.csv"; zip << @staffs.to_csv_staff
zip.put_next_entry "locations.csv"; zip << @locations.to_csv_locations
zip.put_next_entry "pricings.csv"; zip << @salonpricings.to_csv_pricings
zip.put_next_entry "services.csv"; zip << @salonservices.to_csv_salonservices
zip.put_next_entry "appointments.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/appointments.zip")
zip.put_next_entry "inventories.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/inventories.zip")
zip.put_next_entry "tickets.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/tickets.zip")
zip.put_next_entry "addonmappings.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/addonmappings.csv")
end
file_stream.rewind
respond_to do |format|
format.zip do
send_data file_stream.read, filename: "salon_set.zip"
end
end
file_stream.rewind
File.open("#{Rails.root}/app/assets/csvs/salon_set.zip", 'wb') do |file|
file.write(file_stream.read)
end
end
Link 到我的存储库,如果有帮助的话
https://github.com/atayl16/data-wizard/blob/master/app/controllers/application_controller.rb
https://github.com/atayl16/data-wizard/blob/master/app/models/application_record.rb
我知道一定有比一遍又一遍地写这些相同的行更好的方法。代码有效,我的网站有效(令人惊讶),但如果任何经验丰富的开发人员看到存储库而不笑,我会感到尴尬。感谢您的帮助!
最后,我最终使用元编程来清理它。这是一个示例,为了简洁起见,我从数组中排除了一些项目:
["bundle", "attendee", "location", "membership", "client", "staff"].each do |new_method|
define_method("#{new_method.pluralize}") do
instance_variable_set("@#{new_method.pluralize}", new_method.camelcase.constantize.all)
instance_var = instance_variable_get("@#{new_method.pluralize}")
send_data instance_var.public_send("to_csv_#{new_method.pluralize}"), filename: "#{new_method.pluralize}.csv"
end
end
我能够从新创建的导出控制器中删除 30 个方法。这是上推更改后的代码https://github.com/atayl16/data-wizard/blob/0011b6cf8c1fe967d73a569fa573cedc52cb8c72/app/controllers/export_controller.rb
我有一个应用程序,其唯一目的是播种数据文件并将数据添加到用户压缩和导出的不同 CSV 文件中。我的应用程序控制器充满了看起来像这样的行:
def export_tips
@appointments = Appointment.order('service_id')
send_data @appointments.to_csv_tips, filename: 'tips.csv'
end
def export_ticketpayments
@appointments = Appointment.order('service_id')
send_data @appointments.to_csv_ticketpayments, filename: 'ticketspaymentitems.csv'
end
def export_batchmanifest
@batchmanifests = Batchmanifest.all
send_data @batchmanifests.to_csv_batchmanifest, filename: "batch_manifest-#{Date.today}.csv"
end
def export_pets
@clients = Client.all
send_data @clients.to_csv_pets, filename: 'pets.csv'
end
def export_clients
@clients = Client.all
send_data @clients.to_csv_clients, filename: 'clients.csv'
end
我在应用程序控制器中有它,因为我在多个不同的领域使用它,包括创建单个 CSV 导出和创建内部有多个 zip 和 CSV 的复杂 zip 文件。
我尝试清理代码的一些事情包括:
- 这个的不同变量: def csv_export(模型,文件名) @model.pluralize = (model.titleize).all send_data @model.pluralize.filename, 文件名: 文件名 结束
- 每个都在自己的控制器中(无法从不同的视图和其他控制器轻松访问它们)
- 我也想弄清楚如何创建自己的模块,但无法做到。
我的申请记录同样糟糕,重复的行只是为了导出 CSV:
def self.to_csv_appointments
attributes = %w[appointment_id location_id employee_id client_id child_id notes
has_specific_employee start_time end_time]
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
def self.to_csv_appointmentservices
attributes = %w[appointment_id service_id price duration]
CSV.generate(headers: true) do |csv|
csv << attributes
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
def self.to_csv_tickets
attributes = %w[ticket_id location_id client_id ticket_status employee_id
employee_id start_time]
headers = %w[ticket_id location_id client_id status employee_id
closed_by_employee_id closed_at]
CSV.generate(headers: true) do |csv|
csv << headers
all.each do |appointment|
csv << attributes.map { |attr| appointment.send(attr) }
end
end
end
对于应用程序记录,我尝试了与应用程序控制器列出的类似方法,但无济于事。同样,我使用应用程序记录中的代码而不是单个模型文件中的代码,因为我需要在网站的多个部分访问这些代码。
来自应用程序控制器的代码主要用于视图文件上的静态控制器和按钮。我需要能够创建文件集,如下所列,但也允许用户仅导出一个 CSV。
从静态控制器构建 zip 文件的示例:
def create_appointments_zip
file_stream = Zip::OutputStream.write_buffer do |zip|
@appointments = Appointment.order('service_id')
zip.put_next_entry "appointment_manifest.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/appointment_manifest.csv")
zip.put_next_entry "appointments.csv"; zip << @appointments.to_csv_appointments
zip.put_next_entry "appointment_services.csv"; zip << @appointments.to_csv_appointmentservices
zip.put_next_entry "appointment_statuses.csv"; zip << @appointments.to_csv_appointmentstatuses
end
file_stream.rewind
File.open("#{Rails.root}/app/assets/csvs/appointments.zip", 'wb') do |file|
file.write(file_stream.read)
end
end
def export_salonset
create_appointments_zip
create_tickets_zip
create_inventory_zip
create_memberships_zip
file_stream = Zip::OutputStream.write_buffer do |zip|
@saloncategories = Saloncategory.all
@salonservices = Salonservice.all
@clients = Client.all
@locations = Location.all
@salonpricings = Salonpricing.all
@staffs = Staff.order("location_id")
zip.put_next_entry "batch_manifest.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/batch_manifest_simple_salon.csv")
zip.put_next_entry "categories.csv"; zip << @saloncategories.to_csv_saloncategories
zip.put_next_entry "clients.csv"; zip << @clients.to_csv_clients
zip.put_next_entry "employees.csv"; zip << @staffs.to_csv_staff
zip.put_next_entry "locations.csv"; zip << @locations.to_csv_locations
zip.put_next_entry "pricings.csv"; zip << @salonpricings.to_csv_pricings
zip.put_next_entry "services.csv"; zip << @salonservices.to_csv_salonservices
zip.put_next_entry "appointments.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/appointments.zip")
zip.put_next_entry "inventories.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/inventories.zip")
zip.put_next_entry "tickets.zip"; zip << File.binread("#{Rails.root}/app/assets/csvs/tickets.zip")
zip.put_next_entry "addonmappings.csv"; zip << File.binread("#{Rails.root}/app/assets/csvs/addonmappings.csv")
end
file_stream.rewind
respond_to do |format|
format.zip do
send_data file_stream.read, filename: "salon_set.zip"
end
end
file_stream.rewind
File.open("#{Rails.root}/app/assets/csvs/salon_set.zip", 'wb') do |file|
file.write(file_stream.read)
end
end
Link 到我的存储库,如果有帮助的话 https://github.com/atayl16/data-wizard/blob/master/app/controllers/application_controller.rb https://github.com/atayl16/data-wizard/blob/master/app/models/application_record.rb
我知道一定有比一遍又一遍地写这些相同的行更好的方法。代码有效,我的网站有效(令人惊讶),但如果任何经验丰富的开发人员看到存储库而不笑,我会感到尴尬。感谢您的帮助!
最后,我最终使用元编程来清理它。这是一个示例,为了简洁起见,我从数组中排除了一些项目:
["bundle", "attendee", "location", "membership", "client", "staff"].each do |new_method|
define_method("#{new_method.pluralize}") do
instance_variable_set("@#{new_method.pluralize}", new_method.camelcase.constantize.all)
instance_var = instance_variable_get("@#{new_method.pluralize}")
send_data instance_var.public_send("to_csv_#{new_method.pluralize}"), filename: "#{new_method.pluralize}.csv"
end
end
我能够从新创建的导出控制器中删除 30 个方法。这是上推更改后的代码https://github.com/atayl16/data-wizard/blob/0011b6cf8c1fe967d73a569fa573cedc52cb8c72/app/controllers/export_controller.rb