Working on a rails/angular recipe-maker project today with some help from Aaron Figueroa. I thought it might be useful to write out the steps we went through so I can look back and try this again!
1. Rails new project:
rails new recipe-maker --skip-javascript
Then bundle install. We didn't add a --database=postgresql.
2. Rails models. Created these models including a join:
rails g model Recipe name:string --no-test-framework
rails g model Ingredient name:string --no-test-framework
rails g model RecipeIngredient recipe_id:integer ingredient_id:integer--no-test-framework
3. Migrate. In Rails 5 you can now run (rails -v to see version):
rails db:migrate
4. Seeding. Aaron stubbed out seed info
recipe = Recipe.create(name: "poundcake")
recipe2 = Recipe.create(name: "pad thai")
ingredient = Ingredient.create(name: "noodles")
ingredient2 = Ingredient.create(name: "milk")
recipejoin = RecipeIngredient.create(recipe_id:recipe.id, ingredient_id: ingredient2.id)
recipejoin2 = RecipeIngredient.create(recipe_id: recipe2.id, ingredient_id: ingredient.id)
then: rails db:seed
5. Test to see if seed data is accessible:
rails c
recipe = recipe.first
this returns:
Recipe Load (0.2ms) SELECT"recipes".* FROM "recipes" ORDER BY "recipes"."id" ASC LIMIT ? [["LIMIT", 1]]
=> #<Recipe id: 1, name: "poundcake", created_at: "2016-08-29 17:33:51", updated_at: "2016-08-29 17:33:51">
6. Pretty sure next we created models with activerecord associations.
ingredient.rb:
class Ingredient < ApplicationRecord
has_many :recipe_ingredients
has_many :recipes, through: :recipe_ingredients
end
recipe.rb
class Recipe < ApplicationRecord
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
end
recipe_ingredient.rb
class RecipeIngredient < ApplicationRecord
belongs_to :recipe
belongs_to :ingredient
end
7. Create serializers. I need to review serializers as I'm not 100% on their role right at the moment.
rails g serializer Recipe
rails g serializer Ingredient
and inside the files:
ingredient_serializer.rb:
class IngredientSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :recipes
end
recipe_serializer.rb:
class RecipeSerializer < ActiveModel::Serializer
attributes :id, :name
has_many :ingredients
end
8. Create controllers. We added a bunch of the crud methods on in definition which I haven't done much. Good idea Aaron.
rails g controller Recipes index create show update destroy --no-test-framework
rails g controller Ingredients index create show update destroy --no-test-framework
9. Rails Routes to see if our restful routes are lookin good.
rails routes
10. Run our server for the first time to see if we're connected with rails. We are!
rails s (or rails server)
11. In app>javascripts we need an application.js file our manifest file with information on all the files we require to run our app.
//= require jquery
//= require angular.min
//= require angular-ui-router
//= require angular-rails-templates
//= require angular-sanitize.min
//= require bootstrap-sprockets
//= require_tree .
12. Routes.rb Add resources to routes. This might have happened a little earlier!
resources :recipes
resources :ingredients
13. RecipesController. connecting our recipes controller to render json like this (I know a few of these method can be removed):
class RecipesController < ApplicationController
def index
recipes = Recipe.all
respond_to do |format|
format.html
format.json { render json: recipes}
end
end
def create
end
def show
recipe = Recipe.find(params[:id])
render json: recipe
end
def update
end
def destroy
end
end
14. We have added the following to the Gemfile. I don't know what they all do and don't remember the order we added them. It'd be worth looking up each one again and thinking through why we need it.
gem 'jbuilder', '~> 2.5'
gem 'jquery-rails'
gem 'active_model_serializers', '~> 0.10.0'
gem 'jbuilder', '~> 2.5'
gem 'rack-cors'
gem 'angular-rails-templates'
gem 'bootstrap-sass', '~> 3.3.6'
gem 'autoprefixer-rails'
15. Find these files (ie, angular-ui-router.js) and add to app>javascripts. From here we are testing against the server and beginning to set up angular. Hoping I have the order of events right here. Let's see if I can remember.
16. Routes.rb. We have already added resources to our routes. get and root we added in here as well:
Rails.application.routes.draw do
get 'home/index'
resources :recipes
resources :ingredients
root 'home#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
17. Added a home controller manually. Not sure how central this is to our operations. I might have done this in the beginning?
class HomeController < ApplicationController
def index
end
end
18. App.js in app>assets>javascripts>app>app.js. We've rerouted this to look for template files but the rails views we did I've listed next.
angular
.module('app', ['ui.router', 'templates', 'ngSanitize'])
.config(function($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/',
templateUrl:'home.html',
controller: 'HomeController as vm'
})
.state('home.recipes', {
url: 'recipes',
templateUrl: 'recipes.html',
controller: 'RecipesController as vm'
});
$urlRouterProvider.otherwise('/');
});
19. Views. views>layouts>application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title>RecipeMaker</title>
<%= csrf_meta_tags %>
<%= stylesheet_link_tag 'application', media: 'all' %>
<%= javascript_include_tag 'application'%>
</head>
<body ng-app="app">
<%= yield %>
</body>
</html>
and views>recipes index.html.erb:
<h1>Recipes#index</h1>
<p>Find me in app/views/recipes/index.html.erb</p>
<div ng-controller="RecipesController as vm">
<div ng-repeat ="recipe in vm.recipes">
{{recipe.name}}
</div>
</div>
20. I don't really appreciate yet the different between using templates vs rails views. The angular ones keep things in the front end. I need to research this some. In app>assets>javascripts>app we create a home folder and a recipe folder for these files. app>assets>javascripts>app>home:
home.controller.js:
angular
.module('app')
.controller('HomeController', HomeController)
function HomeController() {
console.log('this is the home controller');
}
and
app>assets>javascripts>app>recipes>recipes.controller.js
function RecipesController($scope){
var vm = this;
debugger;
vm.recipes =
[
{
id: 1,
name: "poundcake",
ingredients: [
{
id: 2,
name: "milk"
}
]
},
{
id: 2,
name: "pad thai",
ingredients: [
{
id: 1,
name: "noodles"
}
]
}
]
}
angular
.module('app')
.controller('RecipesController', RecipesController);
21. Templates. app>assets>javascripts>templates. Important. Not the app folder. recipes.html (currently emtpy)
and home.html:
This is the home.html file in angular
<ui-view></ui-view>
Things I need to work on
1. Review everything we added to the gemfile and what it does
2. Review everything we added to the manifest file and what it does
3. Review serializers and what they do.
4. Rethink the routing. How do the template files, app.js and controller.js files work together?
5. Writing states in app.js
6. What is postgresql?
7. How and what do we build on this structure?
8. Nav bar stuff