$users = User::with('ogrenciler.foto')->get();
Bu şekilde yaparsanız kullanıcıları, öğrencileri ve öğrenciye ait fotoğrafı çekmiş olursunuz (Özellikle fotolar değil de foto yazdım çünkü hasOne yani one-to-one ilişkisi kurduğunuza göre sadece bir fotoğraf olacağı için foto şeklinde tekil yazmak daha uygun olur.)
Elbette bu join değil de eager loading olduğu için size 2 ya da 3 sorguya mal olacaktır. Derseniz ki join ile tek sorguda halletmek daha mantıklı değil mi? Şöyle, join kullandığınızda kompleks işlemlerden feragat etmiş oluyorsunuz, sorgu sayısı ve bellekten kazanmış oluyorsunuz; eager loading kullandığınızda ise daha fazla sorgu çalıştırılıyor ve bellek kullanıyorsunuz ama kompleks işlemleri daha kolay halletmiş oluyorsunuz. (Joinleri kolaylaştırmak için scope kullanabilirsiniz:
https://laravel.com/docs/5.5/eloquent#query-scopes)
Sizin yazdığınız gibi basit ilişkilerde elbette eager loading kullanmak daha mantıklı. Ne zaman performans çok çok daha önemli olur, o zaman join kullanırsınız.
Şöyle bir şey de var, join her zaman daha performanslı değildir, küçük küçük sorgular birden fazla tablo ile yapılan kompleks joinli sorgulardan daha performanslı çalışabilir. Dengeyi siz bulacaksınız.