Here's the Gurobi code to solve the optimization problem:

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("food_optimization")

# Create variables
bagged_salads = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="bagged_salads")
oreos = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="oreos")
tomatoes = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="tomatoes")
bowls_of_cereal = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="bowls_of_cereal")
green_beans = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="green_beans")

# Set objective function
model.setObjective(6.92 * bagged_salads + 1.13 * oreos + 9.28 * tomatoes + 8.53 * bowls_of_cereal + 3.56 * green_beans, GRB.MAXIMIZE)

# Add constraints
model.addConstr(4 * bowls_of_cereal + 4 * green_beans >= 4, "protein_constraint1")
model.addConstr(2 * oreos + 1 * bowls_of_cereal >= 9, "protein_constraint2")
model.addConstr(4 * bagged_salads + 1 * bowls_of_cereal >= 8, "protein_constraint3")
model.addConstr(4 * bagged_salads + 2 * oreos >= 6, "protein_constraint4")

model.addConstr(3 * bagged_salads + 4 * green_beans >= 15, "iron_constraint1")
model.addConstr(1 * oreos + 4 * green_beans >= 16, "iron_constraint2")
model.addConstr(3 * bagged_salads + 2 * bowls_of_cereal + 4 * green_beans >= 23, "iron_constraint3")
model.addConstr(3 * bagged_salads + 1 * oreos + 2 * bowls_of_cereal >= 23, "iron_constraint4")
model.addConstr(4 * tomatoes + 2 * bowls_of_cereal + 4 * green_beans >= 23, "iron_constraint5")


model.addConstr(5 * oreos + 2 * tomatoes >= 3, "carb_constraint1")
model.addConstr(5 * bagged_salads + 5 * oreos >= 8, "carb_constraint2")
model.addConstr(5 * bagged_salads + 2 * green_beans >= 4, "carb_constraint3")
model.addConstr(2 * tomatoes + 2 * green_beans >= 7, "carb_constraint4")
model.addConstr(2 * tomatoes + 3 * bowls_of_cereal >= 5, "carb_constraint5")


model.addConstr(5 * tomatoes + 1 * bowls_of_cereal <= 16, "protein_ub1")
model.addConstr(4 * bagged_salads + 1 * bowls_of_cereal <= 19, "protein_ub2")
model.addConstr(4 * bagged_salads + 4 * green_beans <= 34, "protein_ub3")
model.addConstr(1 * bowls_of_cereal + 4 * green_beans <= 49, "protein_ub4")
model.addConstr(2 * oreos + 4 * green_beans <= 38, "protein_ub5")
model.addConstr(2 * oreos + 5 * tomatoes <= 38, "protein_ub6")
model.addConstr(4 * bagged_salads + 5 * tomatoes <= 50, "protein_ub7")


model.addConstr(3 * bagged_salads + 1 * oreos <= 57, "iron_ub1")
model.addConstr(4 * tomatoes + 4 * green_beans <= 66, "iron_ub2")


model.addConstr(2 * tomatoes + 3 * bowls_of_cereal <= 24, "carb_ub1")
model.addConstr(5 * bagged_salads + 5 * oreos <= 19, "carb_ub2")



# Add resource constraints (using dictionary provided in the prompt)
resource_data = {'r0': {'upper_bound': 63, 'x0': 4, 'x1': 2, 'x2': 5, 'x3': 1, 'x4': 4}, 
                 'r1': {'upper_bound': 115, 'x0': 3, 'x1': 1, 'x2': 4, 'x3': 2, 'x4': 4}, 
                 'r2': {'upper_bound': 49, 'x0': 5, 'x1': 5, 'x2': 2, 'x3': 3, 'x4': 2}}

for resource, data in resource_data.items():
    model.addConstr(data['x0'] * bagged_salads + data['x1'] * oreos + data['x2'] * tomatoes + data['x3'] * bowls_of_cereal + data['x4'] * green_beans <= data['upper_bound'], resource)


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for v in model.getVars():
        print(f"{v.varName}: {v.x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization ended with status: {model.status}")

```