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 @adriguy,

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 @adriguy

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 @adriguy , 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!

1 Like

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

1 Like

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 @adriguy

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!

2 Likes

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 ....