0

I tried several methods I found online but none worked and they weren't specifically targeting the problems I'm having. Basically I have a recipes Rails app, and using Angular, I have to:
(1) Allow the user to add one or more ingredients and directions in the form, like this: http://jsfiddle.net/V4BqE/
(2) Save the ingredients and directions as an array data type in the Rails database (I'm using postgresql), sort of like this but without using $scope: How to create an Array with AngularJS's ng-model

Schema:

  create_table "recipes", force: :cascade do |t|
    t.string   "title"
    t.integer  "difficulty"
    t.integer  "time"
    t.integer  "servings"
    t.string   "description"
    t.string   "ingredients",              array: true
    t.string   "directions",               array: true
    t.integer  "category_id"
    t.integer  "author_id"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

Controller:

(function() {
    'use strict';

    function NewRecipeController ($location, RecipeService, CategoryService) {
        var vm = this;

        CategoryService.getCategories()
            .then(function(response) {
                vm.categories = response.data;
            });

      vm.addRecipe = function() {
        var data = {
            title: this.title,
            difficulty: this.difficulty,
            time: this.time,
            servings: this.servings,
            description: this.description,
            // Im stuck trying to figure out the following 2 lines
            ingredients: this.ingredients,
            directions: this.directions,
            category_id: this.category.id
        };

        RecipeService.createRecipe(data);
        $location.path('profile');
      };

    }

    angular
        .module('app')
        .controller('NewRecipeController', NewRecipeController)

}());

Form (just the ingredients and directions section are relevant):

        <form name="newRecipe" novalidate ng-submit="vm.addRecipe()">

            <!-- title -->

            <div class="form-group">
              <label for="title">Recipe Name</label>
              <input class="form-control" type="text" name="title" ng-model="vm.title" required>
            </div>

            <!-- category -->

            <div class="form-group">
                <label for="category">Category</label>
              <select class="form-control" name="category" ng-model="vm.category" ng-options="category.name for category in vm.categories" required></select>
            </div>

            <!-- description -->

            <div class="form-group">
                <label for="description">Description</label>
              <input class="form-control" type="text" name="description" ng-model="vm.description" required>
            </div>

            <!-- difficulty -->

            <div class="form-group">
              <label for="difficulty">Difficulty</label>
              <input class="form-control" type="number" name="difficulty" ng-model="vm.difficulty" min="1" max="5" required>
              <small id="emailHelp" class="form-text text-muted">Enter a number between 1 and 5.</small>
            </div>

            <!-- time -->

            <div class="form-group">
                <label for="time">Time to Make (Minutes)</label>
              <input class="form-control" type="number" name="time" ng-model="vm.time" min="5" step="5" required>
              <small id="emailHelp" class="form-text text-muted">Enter a number that is an increment of 5 minutes.</small>
            </div>

            <!-- servings -->

            <div class="form-group">
                <label for="servings">Servings</label>
              <input class="form-control" type="number" name="servings" ng-model="vm.servings" required>
            </div>

            <!-- ingredients - this is where I'm stuck -->
            <!-- I want to be able to let the user add more input fields if they want and do the same for directions -->

            <div class="form-group" ng-repeat="ingredient in vm.ingredients">
                <label for="ingredients">Ingredients</label>
              <input class="form-control" type="text" name="ingredients" ng-model="vm.ingredients[$index]" required>
            </div>

            <div ng-show="newRecipe.$valid">
                <input class="btn btn-primary" type="submit" value="Create Recipe">
            </div>
        </form>

I understand that I have to save the array as a string. I tried directly saving ingredients: '["ingredient1", "ingredient2"]' and ingredients: '["ingredient1, ingredient2"]', but both just saved as ingredients: ["ingredient1"]. I've also tried JSON.stringify(ingredients). I am using a serializer:

class RecipeSerializer < ActiveModel::Serializer
  attributes :id, :title, :difficulty, :time, :servings, :description, :ingredients, :directions

  belongs_to :category
  belongs_to :author, class_name: 'User'
  # has_many :favorites
    has_many :favorited_users, through: :favorites, source: :user
end

Recipe Rails controller #create:

  def create
    @recipe = Recipe.new(recipe_params)
    @recipe.author = current_user
    @recipe.save
  end

Full code on Github: https://github.com/auranbuckles/world-recipes

4
  • could be helpful to see more of your angular code. Putting together a fiddle of what you have already would be awesome! Commented Nov 27, 2016 at 4:04
  • Doublecheck the Rails "Recipe" model; there should be something in it that looks like serialize :ingredients, Array and serialize :directions, Array. Also track down the Rails controller that this is being submitted to; there should be a method that extracts the recipe params before it's saved; that'd also be useful for debugging this. Commented Nov 27, 2016 at 4:20
  • (you should be able to submit ingredients: '["ingredient1", "ingredient2"] if the Rails model and controller are set up correctly, that's why I'm asking to see those too) Commented Nov 27, 2016 at 4:23
  • Thanks! I added more of my code and the link to the github repo. Just experimented with serialize :ingredients, Array in the model. In this case, if I send ingredients: '["ingredient1", "ingredient2"]' to the backend, I get the error ActiveRecord::SerializationTypeMismatch in RecipesController#create Attribute was supposed to be a Array, but was a String. -- "[\"ingredient1\", \"ingredient2\"]". And if I send a plain array ingredients: ["ingredient1", "ingredient2"] I get a blank [] array sent to the backend. I'm still stuck but I'll keep testing this out. Commented Nov 27, 2016 at 15:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.