Everything You Need to Know About Working With Text Files in Ruby

| Comments

When working with text files in my apps, I never seem to know when to read a file or when to just open it. And once it’s open how to I modify it from Ruby? I generally read through multiple different versions of docs, and end up going with my best bet (all while feeling equally as confused as Jennifer Lawrence). I figured there have to be rules around this..So here it is, consider this your cheat sheet to working with text files in Ruby.

Opening A File

In order to do anything with a file, you have to open it first. Think about an document you receive in your email. Can you read or edit the document without opening it first? Nada.

Let’s say my app file structure looks something like this:

1
2
3
4
5
6
|── app
    ├── lib
    │    └── my_code.rb
    |── fixtures
      ├── info.txt
      │── my_contents.txt

lib/my_code.rb is my ruby file where I will be writing my code to read from fixtures/info.txt and fixtures/my_contents.txt.

So let’s say from inside of lib/my_code.rb, I wanted to open the contents of fixtures/info.txt:

1
file = File.open('../fixtures/info.txt')

I now have the contents of the info.txt stored in a variable called file. It’s important to note that the file variable is storing an instance of the File class. It’s storing an actual File object. You can see what instance methods are available on this file by entering file.methods.

Reading A File

Now that I have my file open, it’s time to read it.

1
file.read

Calling the read method on my File object will display the entire contents of the file as a single string. If the file were a CSV, you’d need to split the string based on a comma.

Writing To A File

In order to write to a file, you actually need to change the way in which you open it in the first place. Let’s say I’m going to write to fixtures/my_contents.txt:

1
2
3
4
File.open('../fixtures/my_contents.txt', 'w') do |file|
  file.write("I am writing to a file from my program")
  file.close
end

This time, you have the pass the argument 'w', which is the flag to write to a file. Without this additional argument to the open method, you can’t write to your file.

Next, inside the do block, you use the method write method. This method accepts an argument: the string you wish to write to your file. Finally, we call the close method, to close the opened file. And lastly, and end to close our block.

Create Multiple Objects From Single Form in Rails

| Comments

I recently wanted to to create at least 10 Answer objects from a single form. Essentially, I was building a quiz app and wanted people to be able to take a quiz. I finally figured it out, but had to back out to a much simpler sample to fully understand what was going on. So I made an app to create a bunch of puppies.

I generated a new rails app with a single model,Puppy. To start, I knew I wanted to create a form that would eventually look like this:

Step 1:

First, I needed to change my new controller action to create 5 new puppies, instead of just one.

puppies_controller.rb

1
2
3
4
5
6
  def new
    @kennel = []
    5.times do
      @kennel << Puppy.new
    end
  end

Each new puppy that I create Puppy.new is stored in an array named @kennel. This way, later in my create action, I can iterate over @kennel to save each puppy to the database.

Step 2:

This also meant that my form needed to be structured slightly differently. I need the params to contain an array of each individual puppy information. I wanted to structure my form such that the params hash looked like this:

1
2
3
4
5
6
  params = {
    "puppies" = [
      {"name" => "Joe", "breed" => "Pomeranian"},
      {"name" => "Victoria", "breed" => "Mastif"}
    ]
  }

views/puppies/new.html.erb

1
2
3
4
5
6
7
<%= form_tag puppies_path do %>
<% @kennel.each do |puppy| %>
  <% end %>
  <div class="actions">
    <%= submit_tag %>
  </div>
<% end %>

I started out with a form tag, that submits a POST request to the Puppy create action. Next, I need to take my array of puppies, which I named @kennel in my new controller action and iterate over that array to generate fields for each specific puppy in that array. This way I have one single form with many sets of fields.

Now that I have a way to access each instance of the Puppy class that I’m creating, I need to start generating form fields for each attribute. In this case, I only have two attributes, name and breed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<%= form_tag puppies_path do %>
  <% @kennel.each do |puppy| %>
    <%= fields_for 'puppies[]', puppy do |p| %>

      <div class="field">
        <%= p.label :name %><br>
        <%= p.text_field :name %>
      </div>
      <div class="field">
        <%= p.label :breed %><br>
        <%= p.text_field :breed %>
      </div>

    <% end %>
  <% end %>
  <div class="actions">
    <%= submit_tag %>
  </div>
<% end %>

I set up <%= fields_for 'puppies[]', puppy do |p| %> so that I can set up the params hash to contain an array of puppies. Basically I’m setting that there will be a key in the params hash called puppies. From there, I set up the text_fields for name and breed.

Step 3:

But this means that I can’t use strong parameters as they are normally used. Strong parameters would expect a key called name and a key called breed inside of a key named puppy.

1
2
3
4
5
6
  params = {
    "puppy" => {
      "name" => "Joe",
      "breed" => "pomeranian"
    }
  }

Instead, it would find those keys inside of a hash, inside of an array, which is the value of the key puppies, which is exactly how I started out trying to design the params:

1
2
3
4
5
6
  params = {
    "puppies" = [
      {"name" => "Joe", "breed" => "Pomeranian"},
      {"name" => "Victoria", "breed" => "Mastif"}
    ]
  }

puppies_controller.rb

1
2
3
  def puppy_params(my_params)
    my_params.permit(:name, :breed)
  end

I set up my puppy_params method to accept an argument, which would be some hash containing the parameters by which I would want to create each instance of my Puppy class. Inside the method, I use the my_params argument and permit those keys (name and breed) to pass through to the Puppy model.

Step 4:

This means I can’t simply call Puppy.create(puppy_params) anymore…

puppies_controller.rb

1
2
3
4
5
6
7
8
def create
  params["puppies"].each do |puppy|
    if puppy["name"] != "" || puppy["breed"] != ""
      Puppy.create(puppy_params(puppy))
    end
  end

  end

Instead, I have to iterate over the value of the key puppies in the params hash. From there, I have the specific hash for each individual puppy. To create a puppy now, I have to call Puppy.create(puppy_params(puppy)). I also had to set up a check to make sure the name and breed keys are not storing empty strings (in the event that someone wanted to only make 3 puppies and not 5).

Step 5:

But this also means that my app breaks if I have a form to just create one single puppy.

application_controller.rb

1
2
3
4
5
6
7
8
9
10
11
def create
    if params.has_key?("puppy")
      Puppy.create(puppy_params(params["puppy"]))
    else
      params["puppies"].each do |puppy|
        if puppy["name"] != "" || puppy["breed"] != ""
          Puppy.create(puppy_params(puppy))
        end
      end
    end
  end

I had to set up an if statement to check if the params has the key "puppy", which is how information is passed back to the controller from the form to create a single instance of the puppy class. If params did in fact have that key, then I have to create an instance of the puppy class by calling Puppy.create(puppy_params(params["puppy"])).Remember, I set up the puppy_params method to accept an argument. I couldn’t just pass params because I took the .require(:puppy) out of the strong params. This method no longer knows how to look inside a hash to find the desired data, it needs to be passed the specific hash. I passed in params["puppy"] as the argument to the puppy_params method.

And finally, I can create 1 puppy, 10 puppies, or 1 billion puppies.

How to Write a Binary Search in C

| Comments

First off, what is a binary search? A binary search, also known as a half-interval search, is an algorithm that finds a target number in a sorted sequence of numbers by comparing the target number to the middle number in the sequence. If the target number is smaller than the middle number, the entire top half of the sequence is ignored.

Let’s break this down with an example. Let’s say we’re looking for the number 51 in this range of numbers

1
0 7 21 34 47 51 89 100 121 151 191 203 500 876 981 1000

There are 16 numbers in this sequence, and in computer programming, we begin counting sequences of numbers at 0, which makes the middle number in this sequence 121. In this case, 51 is less than 121, so every number greater than 121, and 121 itself is ignored, making the sequence of numbers look like this:

1
0 7 21 34 47 51 89 100

Now that we have 8 numbers in the sequence, the middle number is 47. Since 51 is a larger number, we can ignore all the numbers 47 on down, leaving us with 15 89 100. Once again we take the middle number, 89. 51 is smaller, so we ignore 89 and 100, leaving us with just 15. If our target number is 15, we have officially found our target.

So how do we write this in C?

First things first, we need an array that holds all 16 numbers:

1
int numbers[16] = {0, 7, 21, 34, 47, 51, 89, 100, 121, 151, 191, 203, 500, 876, 981, 1000};

Next we need to define our own search function:

1
2
3
4
5
bool search(int value, int values[], int n)
{

  return false;
}

This function, called search takes in 3 arguments, the target number that you’re looking for, value, the array that you’re searching through, values, and the length of the array, n. This method also returns false (or zero) in the case of success.

Now that we have the function set up, some pseudo-code to get us thinking in the right way:

  1. Set up a base case (if there is only 1 item in the array) so that the recursive loop will quit appropriately
  2. Create a variable to store the index of the middle number in the array
  3. Instantiate a new array from the correct half of the original array to search through
  4. Compare the target number to the middle number
  5. If the target number is greater than the middle number, ignore everything from the middle number down and store the larger numbers in a new array and vice versa
  6. Call search function to find the middle again….

Set up a base case

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bool search(int value, int values[], int n)
{
  if (n < 2)
  {
    if (value == values[0])
    {
      return false;
    }
    else
    {
      return true;
    }

  }

}
  return false;
}

In this base case, the first if statement is checking to see if the size of the array n, is less than one, meaning is there only one item in this array? If that statement evaluates to true, the nested if/else statement will kick in. The nested if statement is checking to see if the target number value is the number in the array. If it is, the function will return false, if it isn’t it will return true.

Create a variable to store the index of the middle number in the array

The middle number in the array is going to be n/2. If n is 16, the middle number would be 8. If n is 15, the middle number would be 7.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bool search(int value, int values[], int n)
{
  if (n < 2)
  {
    if (value == values[0])
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  int middle = n/2;

}
  return false;
}

On line 15, we set up a variable middle to store the middle value.

Instantiate a new array from the correct half of the original array to search through

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool search(int value, int values[], int n)
{
  if (n == 1)
  {
    if (value == values[0])
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  int middle = n/2;
  const int MAX = 65536;
  int half[MAX];

  return false;
}

On lines 16 we create a new constant, which stores the number 65536. This massive number will be useful to gaurantee that the search function can handle incredibly large arrays. On line 17 we create a new array called half, declare that it will store up to 65536 integers.

Compare the target number to the middle number

We’re going to need to set up more flow control based on the results of comparing value to the middle number in the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
bool search(int value, int values[], int n)
{
  if (n == 1)
  {
    if (value == values[0])
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  int middle = n/2;
  const int MAX = 65536;
  int half[MAX];
  if (value > values[middle])
  {
  }
  else if (value < values[middle])
  {

  }
  else if (value == values[middle])
  {

  }

  return false;
}

Now we have our logic set up for either situation, if value (the number we’re searching for) is either less than or greater than or equal to values[middle], which is the number at the middle index of the values array.

If the target number is greater than the middle number, ignore everything from the middle number down and store the larger numbers in a new array and vice versa

Once we’re inside our if statements, we need to be able to select just half of the original array, by storing it in the new array we instatiated previously.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
bool search(int value, int values[], int n)
{
  if (n == 1)
  {
    if (value == values[0])
    {
      return false;
    }
    else
    {
      return true;
    }
  }

  int middle = n/2;
  const int MAX = 65536;
  int half[MAX];
  if (value > values[middle])
  {
    int new_size = n - middle;
    if (value > values[middle])
    {
      int new_size = n - middle -1;
      for (int i = 0, m = middle+1; i < new_size; i++, m++)
      {
        new_array[i] = values[m];
      }
    }
    return search(value, new_array, new_size);
  }
  else if (value < values[middle])
  {
    int new_size = n - middle;
    for (int i = 0, m = 0; i < middle; i++, m++)
    {
      new_array[i] = values[m];
    }
    return search(value, new_array, new_size);
  }
  else if (value == values[middle])
  {
    return true;
  }

  return false;
}

LINES 20-29 In the case that value is greater than values[middle], we want to take the top half of the values array. We first create a new_size variable which stores the size of the top half of the array (n - middle -1). Then we iterate over the top half of the values array place the value of each index in the half array. This for-loop needs to incrementors, i which will iterate through half, and m which stores the index of the middle item in the array and iterates through values. Once we have our new array, we need to call our search function again. This is recursive implementation of a binary search, which means we’re calling a function inside the definition of that function. Our function with return out when it hits the base case, aka when there is only one index left in the array.

And when value is less than values[middle]? We need to take the bottom half of the values array and place those values in an empty half array. Again, we have to call our search function.

An important part here is how we call the search function recursively on lines 29 and 37, return search(value, new_array, new_size);. We need to explicitly return the return value of those recursive calls so that they can move up the tree and the original search function can return the result.

Teaching CLI

| Comments

The Nuts and Bolts: About six months ago I joined Flatiron School to start something really awesome…a program to teach high school students to code. After teaching over 100 students this summer during six two-week camps and the preparations for our after school programs I’ve learned a lot about teaching and coding.

CLI:

When I learned command line, it felt like a necessary evil. This thing I had to learn in order to get to the cool stuff. I wanted to build web apps that people would use and think were awesome. But before that, I had to learn CLI and git and sql and all this stuff. That’s like 3 languages before you even get to the good stuff.

At Flatiron School, we don’t teach coding in contrived environments. Not for our adult immersives, and definitely not for our high school programs. We want give our students the ability to use real tools to build real things. Which means, again…teaching our students to use terminal like the pros. But it sort of seems to suck.

How It’s Taught Now

The best guide available online is Zed Shaw’s Learn CLI the Hard Way.It’s actually a great tutorial to master the commands. It’s how I learned. But let’s think about it for a second. A class of 20 fifteen-year-olds will eat you alive if you hand them that and say “type ‘mkdir director_name’ 10 times, followed by ‘rm -r directory_name’”. Especially on day one!

Our students have never coded before. Never even knew that terminal existed on their computer. Didn’t know that that was life before the GUI. Didn’t even know what a GUI was. So you can’t just give them meaningless exercises to learn this potentially really boring thing.

The single most frequently asked question in every class by most every student is “Why are we learning this? What’s the point?”

What Is The Point?!

Command Line provides an incredibly easy interface to your computer. You don’t spend seconds looking for your lost mouse, clicking icons, waiting for finder to load, waiting for files to load. Typing open Desktop/Development/my_file.rb takes milliseconds! As a developer, your time is expensive, and those seconds you waste navigating through finder add up to minutes and then hours that you waste trying to find and open files. That’s why we claim the best developers never have to touch a mouse.

So How Do You Make It Interesting??

First and foremost, terminal can’t be treated as the boring thing. It has to be cool in and of itself.

Here are some points I’ve tried to emphasize:

1. IT’S NOT SCARY!! You cannot explode your computer into a million pieces just by typing in a bad command. Just bang on the keyboard and press enter. It’ll be ok I promise.

2. A themed story makes a world of difference. I’ve used the story of saving a princess from a tower. You have to move through the territory ruled by the castle by creating the directories that make up the different areas of the territory as well as create files for the different people and creatures you meet along the way. This story allows students to repeat the commands over and over and over again, but not bore them to death with random pointless files. This way, they’re on a mission.

3. Say command packs a big punch. You can even have the say command read from a file say -f file_name. You can change voices by passing the -v flag with an argument. It would look something like this say -f file-name -v voice_name. Apple provides Bruce, Kathy, Alex, Fred, Victoria, and Vicki as potential different voices.

4. rm -rf is THE MOST DANGEROUS. But it also make you feel super powerful that you can destroy a computer with four letters and a hyphen.

5. ALL THE TOYS. Just try typing brew install cmatrix. Once it installs enter cmatrix and install feel like the coolest.

Aside You can even incorporate the say command into ruby code. Which is SUPER AWESOME.

1
2
3
def say_hi(name)
  `say "hi #{name}"`
end

Keeping Confidence in the Face of Something New

| Comments

Disclaimer: I originally wrote this post to give as a lightning talk at RubyConf 2013. I signed up a little too late and there wasn’t time for me to give it, so I figured it would make a good blog post.

Hi my name is Victoria Friedman, and I am a very new member of the Ruby community. I’ve been programming for less than a year. Seriously, last January I made my brother spend a good 30 minutes explaining absolute versus relative paths to me. So how did I end up here?

I didn’t come to Ruby from a CS background, I didn’t grow up taking apart the toaster oven like my older brother, instead I wrote poems and drew pictures that my mom turned into postcards. I was an English major at a liberal arts college in TN and wanted to be a writer. So programming?

Last February I started a 12 week intensive course in ruby and rails in New York City called the Flatiron School. And now I’m a rails developer at Time.

For those of you that knew from an early age that programming was for you, I applaud you. You’re so lucky you found your path in life early on. I on the other hand, hit my post-grad quarter life crisis SO hard. Seriously there wasn’t something I didn’t try: coaching, writing, fashion, pastry school. Been there, done that. So I came from the most non-traditional background. And the programming way of thinking was not my specialty.

People tend to stick to things they’re inheritely good at. I hate things I’m bad at, which is why I don’t attempt to paint portraits, or write short fiction stories, or play tennis. I’m bad at it. I’m sure I could learn, but what’s the fun in sucking so badly at something? It’s demoralizing. The biggest shot to the ego. Especially when you’re starting “late in life”

That fact alone should have made me run in the opposite direction. I called directories folders, I’d never heard of a method, and I can’t believe I’m about to admit this, but less than a year ago I thought Java was short for Javascript. I was that clueless.

Progamming is HARD. it is the hardest thing I have ever tried to do in my entire life. Steve Klabnik came and talked to my class at the Flatiron School and I think he described it in the best way I’ve ever heard “when you’re writing code, you’re fixing things that are broken, when it’s fixed, you stop. So programming is just like banging your head against a wall, it feels really good when you stop”

Along with learning to code, and acquiring a job, The Flatiron School really taught me how to check my ego. And really for the benefit of myself.

The advice I tell anyone learning to code, especially people going through programs like mine, is to not be afraid to admit when you don’t know something. Bloomberg will halt a meeting and ask what a word means if someone uses a word he doesn’t know. I am not nearly as influential as Bloomberg. So why should I be afraid to admit that I hadn’t seen a lot (if not most) of the metaprogramming examples Steve Harms used in his talk earlier today, and that I had to google what TTL meant yesterday. If you don’t ask, you’ll never know. You will never learn it unless you can admit you don’t know it.

When you learn to code, you spend a lot of time in “the fog”, to quote my teacher from Flatiron, but the more you use something, the more you understand it. I didn’t think I understood iteration until I realized I was using the each method correctly. I came out of the fog. Over the last 9 months in my learning to code adventures, I’ve continued to dip into the fog, and then come back out. But what makes it so great is when the lights come on, and the best part about it is you can actually demostrate it. You can build something that didn’t previously exist.

Last week, I started trying to fix a bug at work…and then this week, I was still trying to fix the same bug. I spent FIVE DAYS on the same bug. And then I met a friend after work, and he was able to help me fix it in 25 minutes. So why didn’t that make me want to cry? because I’ve been doing this for nine months, and he’s been coding in ruby for 4 years and that doesn’t make him smarter than me, or better than me, or cooler than me. Also he couldn’t fully explain why what we did fixed the bug. But I met someone here at Rubyconf who could. And now I can go back to the city and explain to my friend.

And that’s the beauty of the tech industry. No one can ever know everything there is to know about everything. Somewhere, there is someone that knows more about something than you do, or can do it better. And isn’t that the entire point of open source projects in the first place? And blogs and helping each other.

The Difference Between Url_for and Polymorphic_url

| Comments

url_for is a great Rails helper that returns a URL that has been rewritten according to the options hash passed to it and defined routes. Rails passes all the keys in the options hash to the routing module. There are a few exceptions, including (but not limited to) :only_path, :trailing_slash, and :host. For a full list please see the docs here.

        <%= url_for :controller => "recipes", :action => "show", :id => 1 %>

This would generate a url that looks like this:’http://domain.com/recipes/show/10’

But let’s say you were trying to generate a URL for a polymorphic object, or a nested object, or you just want the absolute path. Let’s take an image object. My image class is polymorphic, and thus belongs to every model as imageable.

        <%= url_for @image :only_path => false %>

Setting :only_path to false generates the full url instead of just the relative path. url_for is really like path_for. You have to pass it an additional argument to return the full URL. But that example returns an error: Wrong number of arguments(2 for 1). Essentially in the example above, you’re passing two arguments– an object and a hash.

But, if you only pass one argument, the object…

            <%=url_for @image %>

This produces a relative path to the image. When you pass an ActiveRecord object to url_for, it causes a lookup on the image class, essentially calling @image.to_params, and use image_path to generate the path.

So how then do you get the full URL with the domain name without doing some hackey "http://mydomain.com" + < my_query_string_generated_from_url_for > ?

This is where polymorphic_url comes in. polymorphic_url is a Rails helper method for calling a named route. It also provides support for nested resources. This helper method is designed to return a full URL, instead of just the relative path, without passing any arguments. If you did want the relative path, polymorphic_path does just that.

So let’s say we’re on an image record

        <%= polymorphic_url(@image) %>

That would be the same as calling image_url(@image). Rails would return “http://mydomain.com/images/1”

So now say you want to access the images from the recipes. This is where the nested support of polymorphic_url comes into play.

        <%= polymorphic_url([recipe, image])%>

This would return “http://mydomain.com/recipes/1/images/1”

So when do you use these handy helpers?A path should always be used unless you’re doing a full redirect.

Additional Resources
1. The Docs for url_for.
2. The Docs for polymorphic_url

Dev Bootcamps Are NOT a Scam. A Hacker’s Perspective

| Comments

This is my response to this horrible article arguing against the validity of hacker schools. And I am a huge supporter, because without the Flatiron School, I literally couldn’t even tell you what I’d be doing with my life. I wrote a really long response to his article in the comments on that post, and it got removed somehow…so I decided to re-write it and put it on my blog. So here goes…

My name is Victoria Friedman and I am a graduate of the second semester of students from the Flatiron School. Prior to my semester I had absolutely ZERO technical background. I graduated from a liberal arts college and was an English Literature major and a French Literature minor. I love to read and write and play sports and do other creative work (like bake and do crafts projects). I wanted to work in the world of publishing, but editorial work is nearly impossible to get involved with. So I spent two months learning some basic HTML and CSS so that I could apply to online magazines and do more than be able to just write content. And that’s when I learned about the Flatiron School. I had never been in terminal until this past January. I didn’t know my elbow from my foot, my left from right. Java? That’s short for Javascript right? Seriously. That’s what I thought.

I pretty much dropped everything the two weeks leading up to the start of the semester and spent around 10 hours a day at school doing the prework, all with the support of Avi and the graduates from the first class. And then the semester started. I should also point out that I was given a scholarship to attend the Flatiron School. I paid NOTHING for three months of learning. which I believe goes against your point of 90k tuitions. Also the Flatiron School’s tuition is nowhere near there to begin with.

And then the semester started. I kissed my social life goodbye and buckled down. I struggled immensely with some basic programming concepts. You can read my blog post about understanding iterations and the each method here and all my other blog posts that document my learning during the Flatiron School since I’ve graduated. Two of which have been included in issues of Ruby Weekly.

As far as only having the ability to produce shitty web apps at the end, I built Starboard with three other students in three weeks. And none of us knew Rails prior. Also, here are some other amazing projects that have come out of the school. Actually, just check out Built which is a CMS for all Flatiron student projects THAT WAS ALSO BUILT BY FLATIRON STUDENTS.

At the end of my interview process, I had more than one job offer. I spent six weeks interviewing and was faced with up to four rounds of interviews with companies, all of which involved technical questions. I was asked to explain the internet, write the reverse method for a string without using .reverse on a whiteboard, construct a multiplayer chess game with thousands of users and describe the caching involved, what a Ruby singleton was, and how inheritance works in javascript. If those are bullshit interview questions, please give me examples of real ones. And I’m really not sure you can fake answering those questions. I just don’t think it’s possible.

I am now a developer at Time Inc on their Internet Application Development Team. If you want to see some of my work since I’ve graduated, please go buy an ecbookbook on Myrecipes.com. I built that. I don’t think you can call the 806th most popular website in the world a shitty web app, and my bosses seem to think I’m qualified enough to lead development for the site. I single handedly run our rails production deployments, manage project timelines and workflow, attend meetings with the sites stakeholders, all while working in collaboration with a team of 20+ people. Yes I make mistakes. But I also learn from them and never make the same mistake twice. Yes things are hard for me sometimes. But I also know I have an abundance of resources (both inside and outside my company) and a brain to figure it all out. Please show me a programmer who knows everything about every programming language. You can’t. It’s impossible. That’s the beauty of the tech industry, there is always something new to learn.

I’ve always told people that my biggest takeaway from my time at the Flatiron School was the ability to learn the things I don’t know. Because no one will ever know it all.

So please do let me know if you would like to speak with any of my bosses. I can easily put you in touch.

Accepts_nested_attributes_for With Name Field in HTML

| Comments

My project at work is interesting because all the teams are very modularized. Yes, we all attend the same standup and have a general idea of what each individual is working on, but that being said the only time I’m really affected by what our front-end team does is when I have to include new markup on the rails side. I never even see the global.js or global.css files.

This week, I spent a lot of time working with one of our front-end developers. We split the work based on our specific abilities in an attempt to finish this sprint as quickly as possible. So this means she’s controling the front end of one of our rails forms. I don’t even have the html for the form in my code base.

So this means in order to make this a form and have the user’s input save to our database as objects, I had to coordinate the implementation of logic, including knowing what to pass in to the name field of the html for the part of the form the front-end developer controls.

I have three classes:

  class Gift
    has_many :gift_recipients
    has_many :recipients, :through => :gift_recipients

    accepts_nested_attributes_for :recipients
  end

  class Recipient
    has_many :gift_recipients
    belongs_to :gifts, :through => :gift_recipients
  end

  class Gift_Recipient
    belongs_to :gifts
    belongs_to :recipients
  end

My form in my views is used to be create a gift, and part of that form is also creating recipients for that gift. Essentially, a user checks a box and mini form appends to the page by javascript, allowing them to enter in a recipient’s email and a message.

accepts_nested_attributes_for allows the creation of a related object along with the main object. So in my example, I’m creating an instance of my Gift class while simultaneously creating an instance of my Recipient class. There is good documentation on this here.

So now what? I don’t have the html for the recipients section of the form in my code, so I have to use the HMTL name field to pass the user’s input back to rails to save it in the database. I was familiar how to do this with just an attribute of an object. For an attribute of the gift, it would look like this:

  <input type="text" name="gift[name]" >

But how does that change with accepts_nested_attributes_for ?

It's actually fairly simple:

<input type="text" name="gift[recipients_attributes][0][email]">
<input type="text" name="gift[recipients_attributes][0][message]">

This would be the input field for an email address for the first instance of Recipient. It follows the typical Rails convention of keeping the associated table name pluralized. The only thing to be aware of, is that the indexing changes based on how many instances of recipients you are creating.

So say my user pushes the button again and wants to create two recipients? The HTML would look a little something like this:

  <input type="text" name="gift[recipients_attributes][1][email]">
  <input type="text" name="gift[recipients_attributes][1][message]">

And voila, on submit, rails understands to create one instance of a gift, as well as two instances of recipients. The through relationship is what attaches my recipients to the gift, so there is naturally an association with that gift to those users.

The Difference Between Javascript Primitive Data Types and Objects

| Comments

I’ve recently been reading Object Oriented Javascript per a colleague’s reccomendation. One thing I got very stuck on, especially coming from Ruby, has been the difference between primitive data types and objects. In Ruby, everything is an object so the concept of primitive data types confused me entirely. Especially this:

  var word = "hello"
  typeof word => "string"

  var word = new String("hello")
  typeof word => "object"

WAT. Literally that’s what I thought. Until I dug a little deeper.

Javascript has five primitive data types:
1. Number
2. String
3. Boolean
4. Undefined
5. Null

Anything that doesn’t belong to any of these five primitive types is considered an object.

BUT each of these five primitive data types has a corresponding object constructor. So to take my above example, you can create a string in two different ways.

First as a primitive data type:

  var word = "hello";

And then as an object:

  var word = new String("hello");

The constructor function uses the new operator. A string object is very similar to a hash of characters.

word;
=> String {0: "h", 1: "e", 2: "l", 3: "l", 4: "o", formatUnicorn: function, truncate: function, splitOnLast: function, contains: function}

The word variable returns a has with each letter index.

And each new object has methods associated with them based on what constructor was used. To continue with the string I created, there are plenty of methods available for string manipulation. (I’ve been told it’s best practice to use primitive data types for strings if you don’t plan on using a lot of the methods.)

word.length; => 5
word[0]; => "h"
word.split(""); => ["h", "e", "l", "l", "o"]
word.toUpperCase(); => "HELLO"

One cool thing, Javascript gives you the ability to treat primitive data types as object. Let’s take a primitive string:

  var greeting = "hello";
  greeting.size; => 5

In this case, behind the scenes, Javascript turns my primitive data type into an object, runs the size method, and then transforms it back to the primitive data type.

You can even check the different between the two:

  var greeting = "hello";
  var word = new String("hello");
  word == greeting; => false

Conceptually, these are two totally different things. They’re not the same type, as per my original confusion one is a string and one is an object. Objects can have additional properties, so those two variables shouldn’t be equal because they’re not.

Allowing the Javascript Onbeforeunload Function to Submit a Form

| Comments

So my last few weeks have been pretty Javascript heavy. I came across a situation where I needed to use the onbeforeunload method so that a popup would occur when a user tried to navigate away from an edit page. This method works on a global scope and is fired before the window is unloaded, or closed. My popup was intended to remind a user to save their changes before leaving.

The only issue with that is that the default functionality of this method ensures that a popup appears when a user tries to leave the page, even on a form submission. So clearly you need to be able to work around this. I don’t want a popup to appear reminding my user to save their changes when they clicked the save button.

So the first step is to define the the function, and it’s return value.

        window.onbeforeunload = function(e) { 
            return "You have unsaved changes, please save them."
        };

The popup generated will look like this:

The only thing about this popup that can be customized is the message, which is defined in the return value of the function. The rest of it is a generic browswer popup. The same popup in Safari will look like this:

Now, any link I click will cause this popup to appear. At this point, even submitting the form will induce this popup. Obviously not what I want.

So the next thing I did was attach a click event to my submit button so that I could customize onbeforeunload’s typical functionality.

    $('#save-button').live('click', function(){
        window.onbeforeunload = function(){};
    });

I am basically redefining onebeforeunload in the scope of that specific click event. Here, nothing will happen. But if I click any other link on my page, the popup will still appear. I only defined onbeforeunload to do nothing in the scope of that one specific click event.

Resources:
1. https://developer.mozilla.org/en-US/docs/Web/API/window.onbeforeunload