Home > OS >  Custom CSV Export in Active Admin Index Page Problems
Custom CSV Export in Active Admin Index Page Problems

Time:08-08

A developer built this app and I'm not well-versed in Ruby at all. So please bear with me. In the Active Admin files, we have several admin pages/tables: artworks, artists, transaction, investors, etc.

In the artworks.rb admin page, I have added the custom CSV export to the bottom:

# frozen_string_literal: true

# rubocop:disable Metrics/BlockLength
ActiveAdmin.register Artwork do
  filter :title
  filter :auction_id, collection: proc {
                                    Auction.where.not(url: [nil, '']).order(:url).pluck(:url, :id)
                                  }, as: :searchable_select
  filter :artist_id, collection: proc { Artist.order(:name).pluck(:name, :id) }, as: :searchable_select

  controller do
    def scoped_collection
      super.includes(:auction, :buyer, :underbidders, :artist)
    end
  end

  index do
    column :lot do |artwork|
      link_to(artwork.lot, admin_artwork_path(artwork)) if artwork.lot
    end
    column :auction
    column :title
    column :artist
    column :image_url
    column 'Auction date' do |artwork|
      artwork.auction&.start_date
    end
    column('Buyer', &:buyer)
    column('Underbidders', &:underbidders)
    column :status
    actions
  end

  show do
    attributes_table do
      row :lot
      row :auction
      row :title
      row :artist
      row :image_url
      row 'Auction date' do |artwork|
        artwork.auction&.start_date
      end
      row('Buyer', &:buyer)
      row('Underbidders', &:underbidders)
      row 'Transactions' do |artwork|
        artwork.transactions.map do |transaction|
          link_to(
            "#{transaction.investor&.name} --- #{price_with_currency(transaction)}",
            admin_transaction_path(transaction)
          )
        end
      end
      row :status
      active_admin_comments
    end
  end

  controller do
    def create
      create! do |success, _|
        success.html { redirect_to collection_path }
      end
    end
  end

  permit_params :lot, :title, :artist_id, :url, :status, :auction_id, :image_url,
                transactions_attributes: %i[
                  id
                  artwork_id
                  investor_id
                  auction_id
                  category
                  price
                  currency
                ]

  form(html: {multipart: true}) do |f|
    f.inputs do
      f.semantic_errors
      f.input :lot
      f.input :title
      f.input :artist, as: :searchable_select, include_blank: true
      f.input :image_url
      f.input :status, as: :select, collection: Artwork.statuses.keys, include_blank: false
      f.input :auction, as: :searchable_select, include_blank: true, collection: Auction.order(:url).pluck(:url, :id)
      f.inputs 'Transactions' do
        f.has_many :transactions, heading: false do |ff|
          ff.input :investor, as: :searchable_select
          ff.input :auction_id, input_html: {value: f.object.auction_id}, as: :hidden
          ff.input :category, as: :select, collection: Transaction.categories.keys, include_blank: false
          ff.input :price
          ff.input :currency, as: :select, collection: Transaction.currencies.keys, include_blank: false
        end
      end
    end
    f.actions
  end

csv do
    column :title
    column :lot 
    column 'Auction' do |artwork|
      artwork.auction&.url
    end
    column 'Artist' do |artwork|
      artwork.artist&.name
    end
    column :image_url
    column 'Auction date' do |artwork|
      artwork.auction&.start_date
    end
    column 'Buyer' do |artwork|
      artwork.buyer&.name
    end
    column 'Underbidders' do |artwork|
      artwork.underbidders&.name
    end
    column 'Price' do |artwork|
       artwork.transactions.map do |transaction|
         transaction&.price
       end
    end
    column 'Currency' do |artwork|
       artwork.transactions.map do |transaction|
         transaction&.currency
       end
    end
  end
end
# rubocop:enable Metrics/BlockLength

It is the last three columns that are not giving me the correct information.

For underbidders, I receive the term "Investor" in all rows. The multiple investor names show up fine in the admin page itself, but not in the CSV export. There could be multiple names so perhaps that is the issue. I've tried several different variations.

If I use column('Underbidders', &:underbidders) as in the index, I get an output that isn't readable on a CSV.

For Price and Currency, this comes from the Transactions table. For price I get items such as [1800000, 1800000, 1800000] and for currency, I get ["usd", "USD"] instead of the one item it should be and without the brackets. They are the same items (for each transaction, the amount and currency is repeated for each investor (buyer and underbidder), but it should only be one final for each transaction.

CodePudding user response:

The Price & Currency make sense -- .map is iterating through a list, applying that function to each member of the list, and returning the list with that function applied.

The problem with that is you are expecting only one value but are getting a list back. Instead, since you don't care about which item in the list, you can grab the first one and its attribute:

    column 'Price' do |artwork|
      artwork.transactions.first&.price
    end
    column 'Currency' do |artwork|
      artwork.transactions.first&.currency
    end

The Underbidders issue is more domain-specific. Have you checked that the method name in app/models/underbidders.rb is actually returning something other than Investor? It may also be a column in the database that is just filled with the value Investor. Or maybe it's a class name.

Since row('Underbidders', &:underbidders) works above, I think this may mean that def to_s is implemented for Underbidder and simply returns the name of the underbidder that you're expecting. You could try:

    column 'Underbidders' do |artwork|
      artwork.underbidders&.to_s
    end
  • Related