Smart Action File upload not saving file with Carrierwave on Rails

Hello,

# controller
def id_doc
    # Get the current card id
    user_id = ForestLiana::ResourcesGetter.get_ids_from_request(params,'bug param').first
    user = ::User.find(user_id)

    # Get the values of the input fields entered by the admin user.
    attrs = params.dig('data', 'attributes', 'values')

    # id_file = attrs['Valid proof of ID'];
    
    user.user_id_doc = attrs['Valid proof of ID']

    user.save!
    render json: { success: "Valid proof of ID uploaded" }
  end

# action
action 'Id Doc', 
    type: 'single', 
    fields: [{
      field: 'Valid proof of ID',
      description: 'Local ID card or passport',
      type: 'File',
      widget: 'file picker',
      is_required: true
    }]
# console log
Started POST "/forest/actions/id-doc?timezone=America%2FNew_York" for 127.0.0.1 at 2021-12-22 12:47:45 -0500
Processing by Forest::UsersController#id_doc as JSON
  Parameters: {"data"=>{"attributes"=>{"values"=>{"Valid proof of ID"=>"data:image/png;name=exp_catgs_2021-12-20.png;base64,iVBORw0KGgoAAAANSUhEUgAABRQAAAJ/CAIAAACGEMioAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QwUERMqN2ZMWwAAIABJREFUeNrs3XVYFPkfB/

....

User Update (0.6ms)  UPDATE "users" SET "user_id_doc" = $1, "updated_at" = $2 WHERE "users"."id" = $3  [["user_id_doc", nil], ["updated_at", "2021-12-22 16:35:10.232741"], ["id", 1]]

Saves but the file is nil.

Edit:
Just wanted to add that I am able to upload images using the regular add/edit features.
Rails 6 app using Carrierwave to upload to AWS.

Thanks for your help.

Hi @muz,

Thanks for reaching out :raised_hands:

Could you please tell us a bit more about what you’re trying to achieve?
If the regular image uploader is working, why do you need to create a smart action exactly?

And can you give us your project name?

Thanks.

Hi @anon34731316,

Thanks for getting back to me.

A user can upload their id document when signing up or do it later. There are a lot of fields on the sign up form, so we want to make it simple later on for admins to upload just the id document - just a one field upload doc smart action.

Does the above shown code have any errors - is that the correct way to create a file upload smart action, or is there a mistake there?

I can share the project name via email.

Thanks again.

Hi @muz :wave: which version of Forest-Liana do you use please ?

From Gemfile.lock: forest_liana (7.4.0)

I’m afraid i’m not able to reproduce.
Can you give me the type of user_id_doc field please?

It is a string - from schema: t.string ā€œuser_id_docā€
That is what Carrierwave uses. It is a type: ā€˜File’ in forest user controller.

I meant to say user.rb collection in forest.

Hi @anon34731316

I changed the type to ā€˜String’ from ā€˜File’ in the action and it is still not uploading the image.

So you don’t see any obvious errors in the code above, and it should work?

Thanks.

I confirm with the same configuration as your i have no issue.
Can you confirm user.user_id_doc contain the file before doing user.save?

So used pry and this is what I get - id_file contains the file, while user…user_id_doc doesn’t seem to.

id_file = attrs['Valid proof of ID'];
    # user.user_id_doc = attrs['Valid proof of ID']
    user.user_id_doc = id_file
    binding.pry
    user.save!

pry(#<Forest::UsersController>)> user.user_id_doc
=> #<UserIDDocUploader:0x00007f00ec300d38
 @cache_id=nil,
 @file=nil,
 @filename=nil,
 @identifier=nil,
 @model=
  #<User id: 1, email: "test1@test.com", created_at: "2021-12-14 03:22:15", updated_at: "2021-12-23 15:57:53", first_name: "test 2", last_name: "test", active: true, provider: nil, uid: "test", admin: false, phone: "1234567890", department_id: nil, remote_id: nil, remote_data: "{}", user_id_doc: nil>,
 @mounted_as=:user_id_doc,
 @staged=false,
 @versions=nil,
 @versions_to_cache=nil,
 @versions_to_store=nil>

[2] pry(#<Forest::UsersController>)> id_file
=> "data:image/png;name=transaction_charts2021-12-20.png;base64,iVBORw0KGgoAAAANSUhEUgAABRMAAAJ8CAIAAADiWKF/AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QwUDygqHWwtGQAAIABJREFUeNrs3XVcFekaB/DfzAm6uwUUCUFMMMDC7u5YddW1W1fXbl07d+1YL+aqa3ehYoCKEgaopNIc6tTM/YNUARGxn+9nP/d6OBPveWfmnXneGobPlIAQQgghhBBCCCHFYCkLCCGEEEIIIYQQipwJIYQQQgghhBCKnAkhhBBCCCGEEIqcCSGEEEIIIYQQipwJIYQQQgghhBCKnAkhhBBCCCGEEIqcCSGEEEIIIYQQipw

Can you give us the user models please?

[4] pry(#<Forest::UsersController>)> user
=> #<User id: 1, email: "test1@test.com", created_at: "2021-12-14 03:22:15", updated_at: "2021-12-23 16:16:27", first_name: "test 2", last_name: "test", active: true, provider: nil, uid: "test", admin: false, phone: "5555555555", department_id: nil, remote_id: nil, remote_data: "{}", kyc_status: "verified", user_id_doc: nil>
[5] pry(#<Forest::UsersController>)> 

[2] pry(#<Forest::UsersController>)> user.phone
=> "5555555555"

Just added a phone filed to make sure that it updates, and it does, while the id_doc doesn’t

I think you have a misconfiguration on your end in your model related to carrierwave or something like that.
So unfortunately i can’t help you.

Thanks for all your help @Arnaud_Moncel and @anon34731316 , I really appreciate it.

Just fyi - I have a receipts smart action also attempting to upload an image, same thing with it too - regular add/edit works, but smart action doesn’t, so I really don’t understand why add/edit works and smart actions don’t.

I will let you know if I figure it out.

Thanks again, and Happy Holidays!

For the update we use

user.update(user_id_doc: attrs['Valid proof of ID'])
# instead of
user.user_id_doc = attrs['Valid proof of ID']
user.save!

I don’t know if it change something,
let me know

Hi @Arnaud_Moncel

Unfortunately that didn’t save the file either. I did:

user.update(user_id_doc: attrs['Valid proof of ID'], phone: attrs['Phone'])

and the phone number was saved, but the file wasn’t.

[1] pry(#<Forest::UsersController>)> user
=> #<User id: 1, user_id_doc: nil, phone: "123 555 5555", ...

Thanks again.

Hi @Arnaud_Moncel @anon34731316

Looks like the solution is to use the carrierwave-base64 gem [1] in order to upload files via a smart action.

Now I am able to upload files via the add/edit user and also a smart action.

[1] GitHub - y9v/carrierwave-base64: Upload files encoded as base64 strings directly to carrierwave

Thanks again!

Happy to hear that! the behavior difference between add/create and smart action is pretty strange, but if it’s work, i’m satisfied.
Thank you for sharing the solution with us.

Hi @Arnaud_Moncel,

After thinking about it a bit more, and comparing the logs of an upload via a regular edit and then via smart action, I don’t know why the smart action upload fails and the edit one works either.

smart action:

Parameters: {"data"=>{"attributes"=>{"values"=>{"image"=>"data:image/jpeg;name=768px-Pomeranian_in_garden.jpg;base64,/9j/4AAQSkZJRgABAQEASABIAAD//gBPRmlsZSBzb3VyY2U6IGh0dHBzOi8vY29tbW9ucy53aWtpbWVkaWEub3JnL3dpa2kvRmlsZTpQb21lcmFuaWFuX2luX2dhcmRlbi5qcGf/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjH ...

via regular edit :

Parameters: {"data"=>{"id"=>"2", "attributes"=>{"image"=>"data:image/jpeg;name=Thai_Ridgeback-Plums%C2%B4jewel.jpg;base64,/9j/4SnWRXhpZgAASUkqAAgAAAAQAAABAwABAAAABAMAAAEBAwABAAAAUgIAAAMBAwABAAAAAQAAAAYBAwABAAAAAgAAAA8BAgAKAAAAzgAAABABAgAIAAAA2AAAABIBAwABAAAAAQAAABoBBQABAAAA4AAAABsBB ....