With Javascript we have to learn to think in functions. You got it partly right with the way you attach your behavior to the button click.
But we need a named function to wrap your code to get it behave as expected.
This is how your code needs to be changed into order to work correctly:
function setClickButton(btnNum) {
document.getElementById('btn-' + btnNum).onclick = function() {
alert(prizes[btnNum]);
};
}
var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
setClickButton(btnNum);
}
Before you had a problem because the script was placing this variable into the same slot in the computer's memory and actually over writing the result, so you click and its undefined.
Now that your code is moved into its own named function, every time the function is called each button gets its own unique place to live within the computer's memory and your code works as expected.
The through associations allow us to describe more complex relationships. With these we can model human social relationships that form tree-like structures such as the family tree.
Lets look at a model of a simple family tree:
- grandmother
- grandfather
- son
- grandson
- granddaughter
- grandson
- daughter
- granddaughter
- grandson
- son
Here we can see all of the "through" relations question. If this were a simple flat relationship our model wouldn't be very accurate or useful. When we look at it on a family tree these abstract concepts become easier to understand.
Each parent in this tree acts as a mediator in the through relationship. A has many through or has one through is the same as a has many or has one, but they has an extra level to them.
Each family has many grandparents, each grandparent has many children and each child has many grandchildren.
But in this model each grandparent has one or many grandsons depending upon whether its the son's son or the daughter's son.
The through relationship allows us to model the hierarchical relationships we find in the real world.
What is SQL Injection? On a basic level its a hacker placing actual sql code into a form input. On a site that's well designed nothing will happen, but on a site where form variables are passed directly from the client to the server in the wrong way it is possible for an attacker to destroy or take over an application simply using their browser as an attack tool.
The most basic mistake to make would be to pass in user input directly from a form:
User.where("email = #{form_email_input}").first
Since we're accessing the form input directly the user could put anything into that email field, including SQL code. While ultimately we also need validation on the model, we also need to pass the variable properly to take advantage of active record's built in sanitization:
Users.where("id = ?", params[:form_email_input}).first
That question mark is a placeholder, instead of passing the query item directly as a string which could contain SQL code active record sanitizes that input before running it.
We want to combine basic correct use of active record with validation on both the client side and the model so we have robust layers of security to prevent SQL injection as well as other forms of hacker attacks against our web applications.
Jquery came before Angular, but is still the most widely used Javascript library today. Originally before the rise of web standards we used Jquery to smooth out these differences between browser implementations and to give us useful shorthands for common tasks.
Angular arose later through a different set of needs. Now we nearly universal support for web standards but the requirements for complexity have made it really hard to build these "next level" web sites.
It gives us a set of metaphors to organize our code and ideas, which is why we call it a "framework" as opposed to jquery being a "library." It fundamentally changes how we approach organizing and approaching our applications. While it has a learnging curve the payback is with a great increase in productivity.
We still use jquery in the industry for handling simple client side tasks. But when we need to implment more complex web applications we turn to frameworks such as angular to help us develop productive, secure and stable applications.
The Big O Cheat Sheet makes it really easy to look at their grid and determine which notation you would want to use based upon the data structure you're using. You can take a look at what kind of data structure you're using, then see the corresponding notation.
For most web development we deal with algorithms that either run immediately no matter how large the data is, like find(1) that are considered to be 0(1) or we deal with algorithms that tend to use system resources in a linear scale, so find(all) will become more resource intensive as the size of the data set keeps growing bigger, this ia 0(n) in big o notation.
We need to make a couple of minor modifications. Your containers need set heights, without set heights in this layout the layout isn't showing up as you expect.
Take a look at how I modified you pricing class:
.pricing {
width: 100%;
height: 200px;
padding: 20px;
background-color: tomato;
}
You can see I just added a height to the pricing container, so now it fills in the expected area.
I had to add a hight to your pricing tier:
.pricing-tiers {
width: 960px;
margin: 0px auto;
height: 200px;
background-color: #ddd;
}
With these kind of container layouts we need to give the containers some kind of height value or they will collapse to a basic fallback dimension which won't look anything like the layout we're trying to acheive.
In order to get the lists to not have bullet points and to have the proper left margin we can use a negative margin to move them over without modifying the entire layout:
ul {
list-style-type: none;
margin-left: -30px;
}