jdkolassa's avatar

Using File Upload on a Model Deletes All Other Fields

So I have a model that is mostly just fields of strings, to be put into the program's main function when used. The last field is an image, that will be added to the final product. I saw the Laracast on Super Simple File Uploading in Laravel 5.3, and thought, "Genius!" But when I tried it, the end result only gave me the first two fields, with everything else blank. So I'm trying to figure out where I'm going wrong.

I'm using the file upload code in my store() method:

public function store(Request $request, Profile $profile)
    {
        
        $new = $request->all();

        request()->file('logo')->store('logos');

        Profile::create($new);

        // dd($request, $profile); // Solely using this for testing when appropriate

        return view('profiles.index')->with('profiles', $profile);
    }

I actually commented out the second line and tried it, and got the same result. I also made the request on the second line $request, but that got me a "Function name must be a string" error. So I'm not sure where the issue is. Should I create a separate controller instead, and use that to manage logos by attaching them to profiles? (I did scaffold that out just in case, but if I don't have to use it I won't as I think that builds in to much complexity.)

Not sure what else I should put here; I'm using a resource controller for Profiles [so Route::resource('profiles', 'ProfilesController');], could that be doing something?

Let me know what else you need.

0 likes
11 replies
kenny11's avatar

@JDKOLASSA I think you need to redirect a user to a url, not to return a view.

So try to redirect a user to a certain url that returns a certain view.

jdkolassa's avatar

Well that hasn't been a problem before, that's always worked (well, once I figured out how the request object was passing stuff back to the database).

Unless you're saying that if files are involved you can't use a view...?

I also realized that I don't have the code set to display the image when you view the profile, but I was going to do that later. Hmm, maybe that's causing a problem...

Snapey's avatar

You are passing the request object to the model and creating a new entry based on what is in the request?

I took from your description that you already had the model saved and you just want to upload and attach an image?

You pass a profile into the controller which implies you have the profile already so why are you not updating that and then saving it?

jdkolassa's avatar

No, I'm creating a new profile. I actually cleared the database while rewriting the migration so to add a field for the image.

I will also add this code to the update method, but I want to get it here first, figure it out, then copy it.

Snapey's avatar

So if you are creating a new profile, you cannot pass it in to the method.

Next, your request obviously needs all the fields for your profile.

Your model needs $fillable attributes for each field you want to set

When you create the profile you should do it like;

$profile = Profile::create($new);

so that you can then pass it to the view.

jdkolassa's avatar

So I've been futzing around with this for the past week, and I think I found something.

(Also thanks for reminding me to put $profile in there; I thought it was, but I might have moved it around trying to figure things out.)

So using dd($request, $profile), I get the following result:

Request {#39 ▼
  #json: null
  #convertedFiles: array:1 [▶]
  #userResolver: Closure {#125 ▶}
  #routeResolver: Closure {#124 ▶}
  +attributes: ParameterBag {#41 ▶}
  +request: ParameterBag {#40 ▼
    #parameters: array:12 [▼
      "name" => "Los Angeles Times"
      "domain" => "www.latimes.com"
      "titlePath" => "meta[property=og:title]"
      "titleTarget" => "content"
      "outletPath" => "meta[property=og:site_name]"
      "outletTarget" => "content"
      "authorPath" => "meta[property=author]"
      "authorTarget" => "content"
      "datePath" => "meta[property=date]"
      "dateTarget" => "content"
      "contentPath" => "div[class=trb_ar_page]"
      "contentTarget" => "innertext"
    ]
  }
  +query: ParameterBag {#47 ▶}
  +server: ServerBag {#44 ▶}
  +files: FileBag {#43 ▼
    #parameters: array:1 [▼
      "logo" => UploadedFile {#28 ▼
        -test: false
        -originalName: "los_angeles_logo.jpg"
        -mimeType: "image/jpeg"
        -size: 24063
        -error: 0
        path: "/tmp"
        filename: "phpdwpkKT"
        basename: "phpdwpkKT"
        pathname: "/tmp/phpdwpkKT"
        extension: ""
        realPath: "/tmp/phpdwpkKT"
        aTime: 2017-03-15 13:30:18
        mTime: 2017-03-15 13:30:18
        cTime: 2017-03-15 13:30:18
        inode: 6191410
        size: 24063
        perms: 0100600
        owner: 1000
        group: 1000
        type: "file"
        writable: true
        readable: true
        executable: false
        file: true
        dir: false
        link: false
      }
    ]
  }
  +cookies: ParameterBag {#42 ▶}
  +headers: HeaderBag {#45 ▶}
  #content: null
  #languages: null
  #charsets: null
  #encodings: null
  #acceptableContentTypes: null
  #pathInfo: "/profiles"
  #requestUri: "/profiles"
  #baseUrl: ""
  #basePath: null
  #method: "POST"
  #format: null
  #session: null
  #locale: null
  #defaultLocale: "en"
}
Profile {#149 ▼
  #fillable: array:13 [▼
    0 => "name"
    1 => "domain"
    2 => "titlepath"
    3 => "titletarget"
    4 => "authorpath"
    5 => "authortarget"
    6 => "outletpath"
    7 => "outlettarget"
    8 => "datepath"
    9 => "datetarget"
    10 => "contentpath"
    11 => "contenttarget"
    12 => "logo"
  ]
  #connection: "mysql"
  #table: null
  #primaryKey: "id"
  #keyType: "int"
  +incrementing: true
  #with: []
  #perPage: 15
  +exists: true
  +wasRecentlyCreated: true
  #attributes: array:6 [▼
    "name" => "Los Angeles Times"
    "domain" => "www.latimes.com"
    "logo" => UploadedFile {#141 ▼
      -test: false
      -originalName: "los_angeles_logo.jpg"
      -mimeType: "image/jpeg"
      -size: 24063
      -error: 0
      #hashName: null
      path: "/tmp"
      filename: "phpdwpkKT"
      basename: "phpdwpkKT"
      pathname: "/tmp/phpdwpkKT"
      extension: ""
      realPath: "/tmp/phpdwpkKT"
      aTime: 2017-03-15 13:30:18
      mTime: 2017-03-15 13:30:18
      cTime: 2017-03-15 13:30:18
      inode: 6191410
      size: 24063
      perms: 0100600
      owner: 1000
      group: 1000
      type: "file"
      writable: true
      readable: true
      executable: false
      file: true
      dir: false
      link: false
    }
    "updated_at" => "2017-03-15 13:30:18"
    "created_at" => "2017-03-15 13:30:18"
    "id" => 5
  ]
  #original: array:6 [▶]
  #casts: []
  #dates: []
  #dateFormat: null
  #appends: []
  #events: []
  #observables: []
  #relations: []
  #touches: []
  +timestamps: true
  #hidden: []
  #visible: []
  #guarded: array:1 [▶]
}

So you can see here, in the request we have the parameters which are correct, and the file which is in the FileBag, but then in the model attributes, you're only getting the first two fields and the file. Not sure why this is happening; any explanation for why that might be? (Also, what might be best way to Google? Just tried that and didn't find much...)

jlrdw's avatar

Have you watched some of the introductory videos?

jdkolassa's avatar

Yes, I have. I have watched Laravel from Scratch (though that was back when it was still 5.1) and have been watching the new videos to see what might have changed, and how that is affecting my code.

If you have a specific video that relates to this, please share it so I may be able to view it.

jlrdw's avatar
 $new = $request->all();

I see @Snapey has already identified that is overriding your fields, sorry I missed his reply at first.

Snapey's avatar
Snapey
Best Answer
Level 122

ok, so check the casing of your attributes

titleTarget in the request != titletargetin the model

etc,etc

jdkolassa's avatar

Actually already noticed that, fixed it, and had the problem resolved.

Then I had to go for a walk because I was so mad at myself for not noticing that tiny little thing.

And they tell you not to sweat the small stuff...

Please or to participate in this conversation.