JS Cheatsheet (work in process)

JavaScript engine makes multiply passes over the same code:

  1. First pass to parse the syntax. During this pass the engine undertakes a process called automatic semicolon insertion.
  2. Second pass to initialise variables and functions and store them in memory. Hoisting: is a JS default behaviour of moving all declarations to the top of the current scope ( to the top of the current script or the current function). Variables and constants declared with let or const are not hoisted.
  3. The third pass is to actually execute the code line-by-line.

First and second passes are called the compilation phase and the third phase is called the execution phase.

Debugging:

No matter what combination of types you write, JS won’t throw an error and will return something, even a non sense and weird something.

  • alert(“Hola!”);
  • console.log(“Hola!”);
  • console.error(“Hola!”);
  • console.warn(“Hola!”);
  • console.table

  • try statement lets you test a block of code for errors.

catch statement lets you handle the error.

  • throw statement lets you create custom errors.

  • finally¬†statement lets you execute code, after try and catch, regardless of the result.

Tests:

  • Unit testing
  • Integration testing
  • End-to end testing

Operators:

Data types:

Everything in JavaScript is data except:

  • operators:+, -, <=, etc.
  • reserved words:function, for, debugger, etc.

A basic type checking with the typeof operator: typeof(42);

The JS’s seven data types:

1.Numbers (primitive data type).

2. strings (primitive data type).

We use ‘single quotes’, “double quotes”, or `backticks.

String concatenation:

3. Booleans (primitive data type).

The following values are falsy:

false

null

undefined

0

NaN

'', ""

Every other value is truthy.

4.Symbols(primitive data type) are primarily used as an alternate way to add properties to objects.

5. Objects:

JS defines 5 types of primitive data types: string, number, boolean, null, undefined. All JS values, except primitives, are objects. In JS almost everything is an object: booleans, numbers and strings, if defined with the new keyword can be objects. Primitive data types represent single values, such as a number, a string or false, instead of a collection of values.

var x = new Boolean(false);

//typeof x returns object 

JS objects: dates, maths, regular expressions, arrays, functions and objects.

Objects are similar to a hash in Ruby or a dictionary in Python. Arrays in JS are objects too.

All keys in an object are strings.

Access a value stored in an Object:

Add a property to an Object:

Delete an property

Arrays:

Add an element:

 

Delete an element:

 

6. Null (primitive data type). Null is an absent object, but when called with typeof returns object.

7. Undefined (primitive data type). It is like a “not yet assigned a value”.

Spread operator (…)

Variables:

Start with a lower case and don’t use spaces, use camelCase.

Mind reserved words or future reserved words.

We can package both of the initialisation steps, declaration and assignment in a single line of code:

Differences between var, const and let.

*Variables declared without a const, let, or var keywords are always globally scoped. You can avoid this using strict mode.

var:

var is function scoped. The scope is limited to the function within which it is defined. If it is defined outside any function, the scope of the variable is global. They are not block-scoped.

Can be reassigned.

var comes with a ton of baggage in the form of scope issues, for example, with var no error is thrown if you declare a variable twice.

let:

let is block scoped. The scope is limited to the block defined by curly braces {}.

Can be reassigned.

const:

const is block scoped. The scope is limited to the block defined by curly braces {}.

Can not be reassigned to anew value, but can be mutated.

Conditional statements:

Functions:

A function is an object that contains a sequence of JavaScript statements.  Declaration:

Function calling or execution:

Parameters. They are locally scoped variables that are usable, scoped, to inside the function. Here name is our parameter.

JS will assign the argument of “Diana” to the parameter name when this function is called.

Function declaration vs function expression

The difference lies in how the browser loads them into the execution context.

Function declarations load before any code is executed.

Function expressions load only when the interpreter reaches that line of code.

If you try to call a function expression before it is loaded you get an error.

Arrow functions:

Arrow functions do not have their own this, it uses  whatever this is defined within the scope it is in.

Looping and iteration:

Iteration is the number of times a loop can be executed, while loop is the code which generate or causes expressions to be iterated.

Looping is the process of executing a set of statements¬†repeatedly until a condition is met. It’s great for when we want to do something a specific number of times (for¬†loop) or unlimited times until the condition is met (while¬†loop).

Iteration is the process of executing a set of statements once for each element in a collection.

Creating object with JS

Definitions:

  • S.O.L.I.D.: 5 principles of Object Oriented Design with JS.
    • S: Single responsibility principle.
    • O: Open closed principle. Open for extensions and closed for modifications, we shouldn’t introduce breaking changes to existing functionality.
    • L: Liskov substitution principle. Every subclass should be substitutable for their parent class.
    • I: Interface segregation principle. A client should never be forced to implement an interface that it doesn’t use or clients shouldn’t be forced to depend on methods they do not use.
    • D: Dependency Inversion principle. Entities must depend on abstractions not on concretions. Importance of higher-order functions.
  • ES6: “ES” ECMAScript, the official name of the JavaScript specification (Harmony – ES5)
  • Higher Order function: Function¬†that may receive a first-class function as an argument and can even return a function.
  • First-class functions: Functions that are treated as objects or assignable to a variable.
  • AJAX: Process of making requests for additional data became known as Asynchronous JavaScript and XML, or AJAX.
  • Closure: When a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.¬†A closure is a feature in JavaScript such that a function holds onto the variables that it had access to when it was declared. Closures can be used to declare functions that have specific variables always defined. JavaScript developers also take advantage of closures to encapsulate data, as we can declare our functions in such a way that the data is only accessible from the returned function, with no way to overwrite the variables captured by the closure.

  • Lexical scope: Where functions and variables are declared.
  • Hoisting: It is JS’s default behaviour of moving declarations to the top of the current scope. Let and const are not hoisted. During a compilation, every declaration ( of variables or functions) are added to the relative scope. Function declaration hoisting differs from variables as the content of the function get hoisted too.

  • Scope: Where something is available. In JS, where declared variables and methods are available within our code. Global scope, function scope, block scope, scope chain, lexical scope ( where functions and variables are declared).

  • Recursion: A recursive function is a function that calls itself.

  • Call back: When we pass a function into another function where in it might be invoked, we refer to the passed function as a callback.

  • forEach: Differences between map and forEach:
    • forEach():¬† It simply calls a provided function on each element in your array. This callback is allowed to mutate the calling array.¬†It returns undefined.¬†forEach()¬†affects and changes our original Array.¬†forEach()¬†may be preferable when you‚Äôre not trying to change the data in your array, but instead want to just¬†do something¬†with it ‚ÄĒ like saving it to a database or logging it out.
    • map(): creates a new array with the results of calling a provided function on every element in the calling array. The difference is that¬†map()¬†utilises return values and actually returns a new Array of the same size.¬†map()¬†returns an entirely new Array ‚ÄĒ thus leaving the original array unchanged.¬†And¬†map()¬†might be preferable when changing or altering data. Not only is it faster but it returns a new Array.

  • Statement vs expression: A statement is a unit of code that accomplish something but does not produce a value. An expression is a unit of code that produces a value.
    • statements: variable declarations, iteration, control flow, debugging.
  • this:¬†keyword that refers to the object it belongs to. Safer if using arrow functions, because arrow function uses whatever¬†this¬†is defined within the scope it is in.
    • This, inside a standalone function will refer to the global object.
    • Outside any function, this refers t the global object, in web browsers this is window.
    • Inside an object method, this refers to the object that received the method call.
    • Inside an standalone function, even one inside a method, this will default to the global object.
    • When using strict mode in a standalone function, as we do inside classes, this will be undefined.
    • We can use .bind, .call and .apply to control the value of this.

Boocket

Boocket is an app for book lovers that want to keep track of the books they want to read.    You can search for books in the Google Book database and add them to your personal wishlist. If you can find anything you like you can create a new book and add it to your personal list and delete it when wished. All books are persisted in the Boocket database, so you will have always your list with you!

I used the create-react-app generator to start my project and in specific npx, a npm package runner, a tool to execute node.js packages.

npx create-react-app google-bookshelf

*I have change the name of the app after that.

My JS files, components and containers

index.js file will have my store with Redux that is connected with the rootReducer and thunk, in order to use async actions. index.js renders <Provider /> as the top level component and wrap my <App /> component.

App.js renders <NavBar />, <Footer /> and it is responsible for the React routes too using react-router-dom. I use react-router-dom, that is react-router plus some link improvements, <BrowserRouter> and <NavLink>.

<SearchableBookListContainer¬†/>¬†renders a form and takes care of its ‘query’ state. After the query, it renders a link list of books. This container is connected to the store to dispatch the action of searching and adding an item to the wishlist plus a list created after our search, the searchBookList. The list rendered with the results of the search has nested links to the book itself. Inside Link¬†I¬† pass a pathname and a state with the book object and in my representational Book component I will get this info as props from Link react-router. I can access them as props.location.state.

<WishListContainer /> is connected to the store and gets the wishlist from here and renders it. It dispatch two actions, getMyWishList that fetches my API end point for a list of books and the deleteBook action. The list of books rendered follows same pattern as the one displayed in <SearchableBookListContainer />, and includes links to the book itself.
<CreateBook /> is a container connected to the store to dispatch the action of adding a new book and renders a form to create it.
<Book />, <Home />, <Footer /> and <NotFound /> components are representational components.
<NavBar /> takes care of all links importing from react-router-dom NavLink.

My source for the data is Google Books API. The Google Books API allows a maximum of 40 returned results and can sort only by search relevance and publish dates. I used the first functionality.

Using Redux and Thunk

Redux is a predictable state container for JavaScript applications. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test.‚Ää‚ÄĒ‚Ä䬆https://redux.js.org/

I will use Redux to organize and have all my states in the same place and Thunk as a middleware to help me alter the behaviour of my actions, allowing me asynchronous requests. I will need to dispatch an action saying I am loading data, then to make a request to the API, and then to wait for the response and then dispatch another action with the response data.

With a plain basic Redux store, you can only do simple synchronous updates by dispatching an action. Middleware extend the store’s abilities, and let you write async logic that interacts with the store.¬†‚Ää‚ÄĒ‚Ä䬆https://redux.js.org/

To install Redux and Thunk in my app I type into my console:

npm install --save redux 

npm install --save react-redux

npm install --save redux-thunk

  1. Initialize my store in index.js using createStore Redux function and pass it down to my top-level <App /> container.

To have access to the store in any of our components we import the react-redux function connectinto the component where we want to have access.

If we want some state we can use:

We can access these data as: this.props.whatEverWeWant.

If we want to dispatch an action and update our store we do something like:

Then to be able to debug I have installed redux-devtools-extension and add this code to my index.js:

Considering web accessibility in my app

I have followed some requirements to take into account web accessibility.

  • WAI-ARIA ( Web Accessibility Initiative – Accessible Rich Internet Applications). I am using Aria HTML attributes.
  • Using as possible fragments <> </>to group together multiple elements and don’t break the HTML semantic.
  • Every HTML form control, such as <input> and <textarea> is labeled accessibly.
  • Create react app has the eslint-plugin-jsx-a11y plugin with a subset of rules activated that checks your code as you develop.

Using docker

I wrapped up the project as a docker image in the Dockerfile.

Creating my API

I follow these instructions and as soon as I have the basics working I do the following:

Create a model for my Book:

I create a seeds file and run my migration:

Generate my controller:

Create a serializer for book and draw my endpoint inside config/routes.rb

How do I connect my react app with my rails API? In my actions. I fetch the end point of my API “books” and GET and POST to it.

This is how my end point looks with my wishlist:

And I think that that’s it! I have enjoyed a lot this project despite it took my a¬† while to figure out Redux functionality. I went through a lot of different problems and learnt a lot. Ah, this bug was my favourite one . I manage to set undefined as my query so my search results were hilarious but very revealing too!

Compare the Triplets

Problem from Hackerrank.

Got some issues figuring out why it didn’t work my function. Two mental notes:

I am still have some problems with indentation and that can cause to put my return value inside the for loop without noticing.

I keep writing the operator “+=” as “=+”. How annoying! I read a good article about it and I finally got it.

My solution:

Address already in use – bind(2) for “127.0.0.1” port 3000 (Errno::EADDRINUSE) | Check what process is running in your localhost

I was trying to create a new rails app and got this error:

Address already in use – bind(2) for “127.0.0.1” port 3000 (Errno::EADDRINUSE)

To fix it I first check which process used my port 3000:

And I got this output:

So now I can stopped it using its pid:

I checked again if something was running in my port 3000 and I didn’t get any output so I run my rails s command and everything worked fine!

Rails with JavaScript – Recipe Manager

So… Starting with my project!

In first place, I want to build the JSON API using the Active Model Serializers gem. I add to my Gemfile:

  • gem ‘active_model_serializers’, that¬†allows you to generate your JSON in an object-oriented and convention-driven manner.

How the JSON API works?

The user makes a request, clicking a link, filling a form… where we had added an event listener. That info is serialized, translated to JSON, and submitted via an AJAX POST or GET request. With that response or data we create a new JS object and then we append the info of that object that we want to show to the DOM using a jQuery selector.

Building a JSON API consists basically in creating the response with the right data to a request and the Active Model Serializers gem is the perfect tool for this. It allows us to format our JSON, select only the information we want, as well as get access to our relationships with a single request.

Setting up the Serializer files

One of the requirements for this project is render at least one index page and one show page via JS and an Active Model Serialization JSON Backend. I was thinking in rendering my recipes index and my recipes show pages.

At the moment¬† I am displaying a list with all the recipes and links to their show page. I am not displaying more info than the title of the recipe in this page, so that’s what I want.

First I add to my Gemfile and bundle install:

  • gem ‘active_model_serializers’

Then I create my serializer file for my recipes. I tipe in my terminal:

rails g serializer recipe

And after creating it I specify which info, attributes and info of its relations I would like to have, in this case, the id and the name of the recipe.

If we specify in our contoller to “render :json” and because I have installed Serializer, Rails will now look to this folder before rendering a resource. Every object we pass to “render :json” in our controllers needs a corresponding serializer file.

* If you want deep nesting by default, you can set a configuration property in an active_model_serializer initializer. (stack overflow)

Create the file: app/config/initializers/active_model_serializer.rb with the following content:

I am going to create my serializers and specify which info I want.

Configuring the Controller to respond to JSON requests.

This is my new index action in the recipes controller:

Uhhm…I just realize that I have a problem. I want different info depending on where the object is rendered. For the index page I only want the title and the id of the recipe but for the show page I want all the info.

Lets make some changes and create two different serializers for recipes.

At the end I created these serializers:

  • category_serializer.rb
  • comment_serializer.rb
  • full_recipe_serializer.rb
  • ingredient_serializer.rb
  • rating_serializer.rb
  • recipe_ingredient_serializer.rb
  • simple_recipe_serializer.rb
  • user_recipe_serializer.rb

A lot of serializers…. I started playing with my app and encounter this error when I was trying to get one of the recipes of my index:

I think that this error is due to the info that the function fetch() is getting is not JSON.
My solution was in the serializers, I wasn’t displaying correctly the info and the relations between the objects. When I was trying to create my JS recipe object my function didn’t have the necessary info. It didn’t have the info for the has_many relations, so when I was trying to create these objects like the comments or the ingredients for the recipe I got this error.
I realize too that I didn’t need a serializer for my user class doing some methods inside the serializers where I wanted that info, for example in the comment serializer I added a method to display the name of the user who create that comment. This is better too in terms of security. I am not displaying my users data.¬†Better not to have the associations because it will give access to the whole user object, including the authenticity token.¬†
This is how my serializers look now:
Two different serializers for a recipe and I have created some methods to get the info I needed and delete the belongs_to relations. I kept the has_many relations trying to avoid defining methods for relations as much as possible, because it’s not clean, neither maintainable¬†but didn’t do it in the case of the user info.

.

I have my serializers and the following images are my changes in my controllers to respond to JSON requests:

Comments controller:

Recipes controller:

Next steps are creating my event listener and JavaScript Object Models.

Creating my files for the JS code

I first add to my Gemfile:¬†gem ‘sprockets-rails’, :require => ‘sprockets/railtie’,¬†a Ruby library for compiling and serving web assets.

I continue adding a new file for all my JS:¬†app/assets/javascripts/main.js. I don’t have to require this directive(main.js) in my manifest (application.js) because this manifest has //= require_tree, which will include all JS files in the same folder that application.js is located.

I’ll have to load the manifest file in my layout, so in the file: app/views/layouts/application.html.erb, inside the head tag, I write:

<%= javascript_include_tag “application” %>
javascript_include_tag is a Rails helper that generates a script tag instructing the browser to load that JS file.

Using arrow syntax of ES6

It differs with the normal JS function by the treatment of this. A normal JS function gets a thisaccording to the calling context (traditional semantics), but the arrow functions keep the this of the context of definition.

Creating a comment with Ajax.

In my comments/new.html.erb I have a form to create a comment. What I want to do is set it up so that I use this form, but use jQuery and AJAX to submit it, so I can handle a JSON response and display the newly created comment without redirecting to the comment show page.

Web users like fast websites and AJAX (Asynchronous JavaScript and XML) is a good technique to keep users engaged. In AJAX we first deliver a page using HTML and CSS and then use JS to add more to the DOM.

Ajax relies on several technologies: promises, XMLHttpRequestObjects, a serialization format called JSON, asynchronous Input / Output and the event loop.

Browsers and servers are only able to pass strings of text to each other. By using JSON, we can structure this text in a way that a browser or server can read as a regular JS object.

I will use the JavaScript fetch() function to apply the AJAX technique.

First step is to set up a document ready in order to detect when our HTML page has loaded, and the document is ready to be manipulated.

Then we hook up an event handler to the form’s submit event, and then block the form from doing an HTML submit. We add¬†an event listener for $(‘div#new_comment’).on(‘submit’, function(event) {} to our document¬†ready().

I am using the jQuery on() method. The on() method attaches one or more event handlers for the selected elements and child elements.

To display error message I read this tutorial.

To create the comment via Ajax I need  a JavaScript Object Model too. I added two prototype functions.

This JMO allows me to get all of the attributes of a comment into javascript by passing the comment resource sent by the controller in response to the AJAX request for json and assigning its properties to a new javascript model object. We can then use the properties of this new javascript model object within my methods on the prototype to help me display the content to the page.

After creating this event listener I follow similar procedure to create another one to handle the comments when they are created in a nested resource, and after that one to get, not post, an index of recipes and show a recipe plus a JS Object model for Recipe, RecipeIngredient, Category and Rating.

Link to my repository.

Rails Portfolio Project – Recipe Manager

Recipe Manager was built using Ruby on Rails framework and Bootstrap. All users can safely signup, login and logout. I created authentication and authorization methods without using any gem. Recipe Manager include a third party signup/login via Github thanks to the OmniAuth gem.

Users can check the recipes, rate and comment them but only admin users can create and edit the recipes and the categories. The user can browse recipes by name and author and all the comments by author and recipe. The app include reasonable validations for its forms and an ActiveRecord scope method to get the newest recipe that can be seen in its own URL, in this case: http://localhost:3000/newest_recipe.

My models:

User

  • Has many recipes
  • Has many comments
  • Has many ratings
  • Attributes: name, email, password_digest, admin, and finally I added uid and provider for the signup/login with OmniAuth.

Recipe:

  • Belongs to a user
  • Has many recipe_ingredients
  • Has many ingredients through recipe_ingredients
  • Has many recipe_categories
  • Has many categories through recipe_categories
  • Has many comments
  • Has many ratings
  • Attributes: name, cooking_time, servings, directions, date created

Ingredient

  • Has many recipe_ingredients
  • Has many recipes through recipe_ingredients
  • Attributes: name

RecipeIngredient

  • Belongs to recipe
  • Belongs to ingredient
  • Attributes: quantity.

Category

  • Has many recipe_categories
  • Has many recipes through recipe_categories
  • Attributes: name

RecipeCategory

  • Belongs to Recipe
  • Belongs to Category

Comment

  • Belongs to user
  • Belongs to recipe
  • Attributes: content

Rating

  • Belongs to user
  • Belongs to recipe
  • Attributes: score

Generate my new application:

Generate my models with their associations and create my db:

*Adding :default => true to boolean in existing Rails column

Implementing a sign-in, login and logout functionality:

In order to encrypt the passwords I will use the gem bcrypt, include “has_secure_password” in my User model and have a password_digest attribute in my users table.

Sign in with Github

  • Add to your gemfile the OmniAuth gem and the provider-specific OmniAuth gem, in this case “omniauth-github”, and run bundle install.
  • Create a file named config/initializers/omniauth.rb. I will contain the following:
  • Create an application in Github.

[Settings/Developer Settings/OAuth Apps/Register a new OAuth application]

In homepage url enter: https://localhost:3000/

In the Authorization url: http://localhost:3000/auth/github/callback

After creating the app you get a client ID and a Client secret.

  • Add dotenv-rails to your Gemfile and run bundle install.
  • Create a file named .env at the root of the application and add your Github credentials.

  • Add .env to your .gitignore file.
  • Create a link to login via Github
  • The User model needs these attributes, all strings: name, email and uid, that it is the user’s ID on Github. *I added a provider attribute later on.
  • Create the route where Github will redirect users in the callback phase of the login process.
  • And in our Sessions controller we find or create the user who logging via github.
  • In our User model:

I want to add some helpful links:

Sinatra Portfolio Project

I would like to make a Content Management System for my daughter’s nursery. They keep the daily information about the children in notebooks full of very easy to lose post its and hope this app can help with it. The daily information will be referred to as activities.

The app provides a database and web interface for users to:
* Sign up, log in or log out securely as a nursery staff or parent.
* Nursery staff can create, read, update, and delete (CRUD) an activity.
* Parents can read only the personal profile page of their children.
* User inputs are validated.
I am using Sinatra to build the app, extended with Rake for working with a SQL database using ActiveRecord ORM.
Sinatra is a Domain Specific Language implemented in Ruby that’s used for writing web applications.
My first steps to create the app are:

-Create a repository in Github.

-The project structure following the MVC conventions.

-Set my environment and my config.ru. I am following the Modular Sinatra Pattern and having a¬†config.ru¬†file is one convention of it. The purpose of config.ru is to detail to Rack (Sinatra gem is built on top of Rack) the environment requirements of the application and start the application, mount my application controllers. Rack is a convention, or specification, that lets web applications “plug” into a common interface for handling HTTP requests. To actually serve requests, we need a¬†web server¬†‚ÄĒ something that can translate HTTP requests into Ruby calls. My gem ‘thin’ is a web server that do this job.

-Create my Gemfile with all gems that I am going to run trough Bundle, which is set up in my environment file.

Here are the gems I want to use:

Sinatra: to create my web application.
activerecord: it is my Object Relation Mapper, links my Ruby models with rows in my database table. It is a gem to have access to the database mapping and associations.

sinatra-activerecord: it gives me access to some Rake tasks.
rake: short for “ruby make”, it is a package that lets me quickly create files and folders, and automate tasks such as database creation.
require_all: for a simplier way to load code.

sqlite3: sqlite is a library that implements a SQL database engine. sqlite is my database adapter gem.

thin: it is a web server.

shotgun: this is my development server.
pry: my debugger.
bcrypt: it is a hashing algorithm for passwords.
tux: it gives me an interactive console that pre-loads my database and
ActiveRecord Associations.
rake: great gem to create actions and tasks, for example a pry console to test the models and the database. It needs a Rakefile in the root directory of the app with the environment specified and requiring¬†‚Äėsinatra/activerecord/rake‚Äô.
Model classes

I think that I will need at least 3 models, User, Activity and Student.

1. User: stores user attributes, including:
* Username
* Email
* Password (Secured with Bcrypt hashing algorithm)
* Nursery_staff, a boolean value to indicate if a user is a nursery staff
2. Activity: stores activity attributes, including:
* Date
* User_id, to associate Activity to User
* Student_id, to associate Activity to Student
* Breakfast
* Morning Snacks
* Lunch
* Afternoon Snacks
* Sleep
* Nappies
* Comments
3. Student: stores student attributes, including:
* Name
* User_id, to associate Student to User
* Key person
* Room
Model Associations
User has many students and has many activities
Student has many activities and belongs to a User (parent).
Activity belongs to a Student and belongs to User.

Is it works?

I am using Visual Studio Code and after creating the structure of my project with very basic info I tried to run shotgun and was getting the following error:

I had a server running in the background. After trying a lot of different things I could stopped it with the following I found in StackOverflow:

Ran lsof -i :9393 (9393 is the port I ran it on).

I killed the process using kill -9 *pid*. My pid was: 58152.

When I ran lsof -i :9393 again, nothing showed up.

I then ran shotgun and everything works fine now.

Model Validations
You can find all info about validations here.
I will use in my controllers the methods save and update, which trigger validations for themselves and will save the object to the database only if the object is valid.
I will use some helpers to validate that some specified attributes are not empty. I want to make sure that a user gives an username and an email and that an activity has a date and a student has a name at least. I will validate the uniqueness of the email too.

 

 

 

 

 

 

Authentication system

Enable sessions in your AppController and use the gem¬†bcrypt.¬†Make sure¬†your user model¬†has_secure_password and that on your users table you store the password like password_digest“.

 

 

 

 

Protecting the session secret by Martin Fowler:

I changed my configuration to look like this:

 

 

 

 

The password fails safe to a secure hex value if SESSION_SECRET is unset.

Database

Create a Database folder (db), run your migrations to create your tables. I have created one table for the students, another table for my users and a last one for the activities.

I run:

rake db:create_migration NAME=create_students

rake db:create_migration NAME=create_users

rake db:create_migration NAME=create_activities

Then modify my migration tables according to my needs.

And finally run rake db:migrate, and all your tables will be added.

Play with my models and the database.

I run tux in my console but I got the following error

config.ru does not support require_relative so I changed my link and everything works fine!

Now it is time to be more creative and design my routes in the controllers and my views. I am using Bootstrap.

To check this project follow the link.