Scaffolding is the easiest way to start, but as the word itself suggests, it's just scaffolding. Rails goes much beyond that. Also, whether to use it or not in practical projects is a huge debate. However, I feel that we can use it to start but it's important that we build our functionalities in it. This will provide us with a template that adheres to best practices to start with, and then builds our code upon it.
After successfully writing our tests, we will write our code to make sure our tests run.
We will first understand our use case:
User story; that is, to create a recipe
User enters the title
Users selects food preferences, food type, cuisine, and the level of difficulty
User enters servings, cooking time, ingredients, and procedure
User saves the recipe
We will start with generating a scaffold. The general format is to write the command followed by the name of model, fields, and datatype of each field shown as follows:
:~/curry-nation$ rails g scaffold recipe title:string cooking_time:string difficulty_level:string food_type_id:integer food_preference_id:integer cuisine_id:integer ingredients:text procedure:text
This will create files that include model, controller, basic views, and skeleton tests.
We can now see what we have already created. In order to see what we have created so far, let's fire up our server and see what we just created by navigating to
localhost:3000
.Now, as we can see, the category values that we added previously are blank textboxes in our form. We would need to create dropdowns for each one of them so that they are selected and sent to the db.
<div class="form-group"> <%= f.label :food_preference %><br> <%= f.select(:food_preference_id, options_from_collection_for_select(FoodPreference.all, :id, :name), {:prompt => 'Please Choose'}, :class => "form-control") %> </div> <div class="form-group"> <%= f.label :food_type %><br> <%= f.select(:food_type_id, options_from_collection_for_select(FoodType.all, :id, :name), {:prompt => 'Please Choose'}, :class => "form-control") %> </div> <div class="form-group"> <%= f.label :cuisine %><br> <%= f.select(:cuisine_id, options_from_collection_for_select(Cuisine.all, :id, :name), {:prompt => 'Please Choose'}, :class => "form-control") %> </div>
As you can see in the preceding code, we are able to populate the values in the select box from our database tables and pass the IDs to the recipe table of the database.
We will define an array in the recipe model and access it in the view. There is also another dropdown required for "level of difficulty" to be defined inside the recipe model. We can create a simple array with the names of difficulty levels as follows:
app/models/recipe.rb DIFFICULTY=%w(Easy Medium Hard)
We can now call the level of difficulties directly inside our views and access the array values by calling it on the model name using
Recipe::DIFFICULTY
, shown as follows:app/views/recipes/_form.html.erb <div class="form-group"> <%= f.label :difficulty_level %><br> <%=f.select :difficulty_level, Recipe::DIFFICULTY,{} , :class => "form-control"%> </div>
At the end of this task, we will be able to create a recipe and add them to categories. However, we have not yet created a real association between them as we discussed earlier. We also saw that we can define arrays and call them directly from our model
class like we did in the case of food type, food preferences, and cuisines.