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

```python
import gurobipy as gp

# Create a new model
m = gp.Model("food_optimization")

# Create variables
ravioli = m.addVar(lb=0, name="ravioli")
knishes = m.addVar(lb=0, name="knishes")
chicken_drumsticks = m.addVar(lb=0, name="chicken_drumsticks")

# Set objective function
m.setObjective(6.2 * ravioli + 1.9 * knishes + 6.3 * chicken_drumsticks, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(0.37 * ravioli + 0.97 * chicken_drumsticks >= 10, "tastiness_ravioli_chicken")
m.addConstr(0.37 * ravioli + 0.83 * knishes >= 3, "tastiness_ravioli_knishes")
m.addConstr(0.37 * ravioli + 0.83 * knishes + 0.97 * chicken_drumsticks >= 3, "tastiness_all")
m.addConstr(1.18 * knishes + 0.14 * chicken_drumsticks >= 14, "protein_knishes_chicken")
m.addConstr(0.39 * ravioli + 0.14 * chicken_drumsticks >= 9, "protein_ravioli_chicken")
m.addConstr(0.39 * ravioli + 1.18 * knishes >= 8, "protein_ravioli_knishes")
m.addConstr(0.39 * ravioli + 1.18 * knishes + 0.14 * chicken_drumsticks >= 9, "protein_all")
m.addConstr(-2 * ravioli + 6 * knishes >= 0, "ravioli_knishes_relation")
m.addConstr(0.37 * ravioli + 0.83 * knishes <= 21, "tastiness_ravioli_knishes_upper")
m.addConstr(0.39 * ravioli + 0.14 * chicken_drumsticks <= 51, "protein_ravioli_chicken_upper")


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    print('ravioli:', ravioli.x)
    print('knishes:', knishes.x)
    print('chicken_drumsticks:', chicken_drumsticks.x)
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print("Optimization ended with status:", m.status)

```
