So when user's current lang. is arabic you want to show the food's arabic name but in case it doesn't exists show them the default name.In this scenario you can never use where clause because regardless of the join a where clause will eliminate any and all rows in the join result that don't match (even if using left joins).If no row in food_translation table has locale = 'ar' therefore in the join result too no row will have locale = 'ar' as a result everything gets eliminated.
What you need to do instead is add the locale ='ar'part in the join condition itself this will give you only those food_translation rows that have locale = 'ar' but without affecting the results of other table joins.Then use COALESCE() (or IFNULL()) operator passing food_translation.food_name as 1st and Food.food_name as the 2nd parameter so if food_translation.food_name is not null it will be used otherwise Food.food_name used.
$food = DB::table('Program')
->leftJoin('Meals', 'Program.meal_id', '=', 'Meals.meals_id')
->leftJoin('Food', 'Meals.food_id', '=', 'Food.food_id')
->leftJoin('food_translation', function ($join) {
$join->on('food_translation.food_id', '=', 'Food.food_id');
$join->on('food_translation.locale', '=', 'ar');
})
->select('Food.food_id','Food.food_name', DB::raw('COALESCE(food_translation.food_name,Food.default_name) as foodname')
)->get();
All in all your raw sql might look like this
SELECT COALESCE(food_translation.food_name, Food.default_name) as foodname,Food.food_id
from program
left join meals on meals.meals_id = program.meal_id
left join food on food.food_id = meals.meals_id
LEFT JOIN food_translation on ( food_translation.food_id = food.food_id and food_translation.locale = 'ar' )