https://avo.cool logo
batch CSV processing
# general
m
I think I've seen a video or guide article for batch processing CSV data but can't seem to find it 🤔
my use case is again attaching participants (=users) to events. essentially what I want to do is upload a CSV with user IDs and use those to create the event user associations
IIUC, an action won't do it because it always needs records to act on, plus I can't upload a file to an action, correct?
or, pass any parameter, for that matter. for starters even a textarea would suffice, the CSV is thrown away afterwards anyway
ah, stupid me, an action has
fields
l
l
Hi @millions-exabyte-27721 there is a recipe on how to export a CSV.
m
yep I'm on that already, thanks
l
> an action won't do it because it always needs records to act on Standalone actions dont need any record selection to trigger
> plus I can't upload a file to an action, correct? False, you can add a file field
This shouldn't be that hard to achieve, let me know if you hit any blocker
Copy code
ruby
class Avo::Actions::Import < Avo::BaseAction
  self.name = "Import"
  self.standalone = true

  def fields
    field :csv, as: :file
  end

  def handle(fields:, **args)
    csv_data = fields[:csv].tempfile

    CSV.foreach(csv_data, headers: true) do |row|
      # Access each column by its header name
      puts "Name: #{row['Name']}"
      # etc. – depends on your CSV headers
    end
  end
end
m
thank you so much, Paul... I actually got quite far with just a
textarea
, which is enough for now but I thought, maybe this would be stuff for another guide?
l
> maybe this would be stuff for another guide? definitively!
m
your hint to tempfiles is great. didn't find that in the docs
l
I asked GPT to do it actually First i debuged inside
def handle
and checked
fields[:csv]
class Then I asked GPT how to get file from that object and iterate rows
But this action can be an recipe for sure, only need to apply it to a real use case
m
So now I'm circling back to this because this time I actually need to import users from a CSV... I generated this action with a
file
field:
Copy code
rb
class Avo::Actions::ImportUsers < Avo::BaseAction
  self.name = "Import Users"
  self.standalone = true
  # self.visible = -> do
  #   true
  # end

  def fields
    field :file, as: :file
  end

  def handle(query:, fields:, current_user:, resource:, **args)
    query.each do |record|
      # Do something with your records.
    end
  end
end
but the dialog doesn't give me an upload field: https://cdn.discordapp.com/attachments/1356194718861496361/1364497974608269333/image.png?ex=6809e344&is=680891c4&hm=d20c209d5f8256ac6c72bb79ff281fbee76ef9a4c3c8301750615d2ac9b0b775& https://cdn.discordapp.com/attachments/1356194718861496361/1364497974889156722/image.png?ex=6809e344&is=680891c4&hm=b6fa852657425b8a1d07af22b7be661d9c23fc99b7a24ccbe2d14235c0b12617&
so... I'm not sure how you got this to work a couple weeks back 🤷 is there a config option I need to set?
ah hang on, it was pundit!
just ... what policy to use here 🤔
l
Seems like authorization
upload_file? = true
m
yep! just what policy do I need here?
is it connected to the User model somehow?
probably not, right?
l
Where are you using the action?
m
in the
User
resource
nothing special:
Copy code
rb
  def actions
    action Avo::Actions::ImportUsers
  end
l
Then
upload_file? = true
should go inside the
UserResource
Since the action is executed on the resource context it uses that resource policy on attachments fields
m
yep, that did it, thanks!