【问题标题】:How to make to_csv into controller with Ruby on Rails如何使用 Ruby on Rails 将 to_csv 制作成控制器
【发布时间】:2021-09-06 10:39:52
【问题描述】:

首先,我接到了任务

  1. 在用户列表上方添加导出按钮
  2. 单击该按钮应下载一个 显示用户字段的 CSV 文件 页面

app/controllers/admins/users_controller.rb

def index
   @users = User.all
   respond_to do |format|
     format.html
     format.csv { send_data @users.to_csv(['email']) }
   end

app/models/user.rb

 def self.to_csv(fields = column_names, options = {})
 CSV.generate(options) do |csv|
   csv << fields
   all.each do |user|
     csv << user.attributes.values_at(*fields)
   end
 end

结束

app/views/layouts/admin.html.erb

<%= form_tag import_admins_users_path, multipart: true, class: 'form-inline' do %>
     <div class="form-group">
       <%= link_to "Export CSV", admins_users_path(format: "csv"), class: 'btn btn-primary' %>
     </div>
   <% end %>

config/routes.rb

namespace :admins do
 resources :users do
   collection { post :import }
 end

结束

方法to_csv不应在模型中

如何将其留在控制器中??

【问题讨论】:

  • 我不确定我是否理解您的问题——“to_csv 方法在控制器中,而不是模型中”?为什么?您当前的实施是否有问题?看来您已经成功解决了最初的任务?
  • to_csv 方法看起来并不真正属于控制器,也不是真正的模型方法。 IMO 它应该是一个视图(鉴于它的工作似乎是格式化和传递数据)或一个普通的 ruby​​ 对象。

标签: ruby-on-rails ruby export-to-csv


【解决方案1】:

CSV 生成方法可能也不应该在控制器中,因为它很难单独测试。胖控制器是一种已知的反模式。

而是创建一个单独的对象来获取用户并将其序列化为 CSV:

class UsersCSVGenerator

  def initialize(users, fields:, **options)
    @users = users
    @options = options
    @fields = fields
  end

  def call
    CSV.generate(**@options) do |csv|
      csv << fields
      @users.each do |user|
        csv << user.attributes.values_at(*@fields)
      end
    end
  end

  def self.call(users, fields: User.column_names, **options)
    new(users, fields: fields, **options).call
  end
end

这基本上是Service Object pattern,非常容易测试。

您可以只将参数传入并编写有关生成的 CSV 的断言,而无需在数据库中创建一堆记录或通过 HTTP 层。

def index
   @users = User.all
   respond_to do |format|
     format.html
     format.csv do 
       send_data UsersCSVGenerator.(@users, fields: ['email']) 
     end
   end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多