Learn Ruby the Hard Way – Exercise 51 Getting Input from a Browser

Here is my work for Exercise 51.
Study Drills

  1. Read even more about HTML, and give the simple form a better layout. It helps to draw what you want to do on paper and then implement it with HTML.

    My form HTML
    My form HTML

    I changed the form to take sender/recipient inputs and used a textarea for the message input. I also added labels for 3 three inputs. I separated each input entry into a div for clearer division and CSS styling.

  2. This one is hard, but try to figure out how you’d do a file upload form so that you can upload an image and save it to disk.
    This one took a few hours at JJ Bean! I reviewed Reading and Writing Files from Exercise 16. First I added a new page upload.erb, this would contain the upload buttons and also show the uploaded images.

    My Image upload form
    My Image upload form

    It is important to add the enctype property when you are sending files. (I didn’t add this in the beginning and couldn’t figure out why I was getting a string instead of a FileUpload object!) Then I went back to app.rb to add the POST handler for ‘/upload/’.

    The post '/upload/' handler
    The post ‘/upload/’ handler

    When ‘/upload/’ receives a form, this code block will be run. First, I assigned the file object to a variable uploaded_file. I used a puts method to print the hash to the terminal so I could look at it. I ran this code, and saw that the file object has filename and tempfile keys. I create a new file in static/images/ with the same file name as the file object. I assign this new file to a variable of target. By opening the file in “w” mode, any files with the same name will be truncated to zero length, and a new file created if the file is not present.
    I then read the contents of the file object by calling the method on the value of tempfile, and write the content to target. I close the target file. When I ran this, I saw the uploaded files appear in the static/images directory. Success!

    function to load image paths
    function to load image paths

    The next step was to display the uploaded image. I first got all the paths to the images using a load_pictures function. This functions returns the paths to all the images under static/images, as an array.  You can specify different file types, this path would get any file under static/images/ that is jpg or jpeg. (For example “/static/images/image1.jpg”.)
    Then, I can call load_pictures inside the post ‘/upload/’ handler to get the array of paths to the images (including the image just uploaded). I assign this to a variable pictures. Finally I call the erb function given :upload_form, and map the local variable of pictures to the array of pictures.

    Added the image tags for uploaded images
    Added the image tags for uploaded images

    In the HTML, I loop through each element of the pictures array and create an image tag with each image path. Here, it is important to remove the ‘static’ (our public directory) from the image path. From the Sinatra documentation, we know that the public directory name is not included in the URL. We also have to add “../” because we are currently in ‘/upload/’ and need to go one level up to the root of the project.

    Image upload success!
    Image upload success!

    Here’s what the page looks like! When you choose and upload an image, the uploaded image is displayed on the page. If I go to my project and look in static/images, I’ll see the new file has been added.

  3. This is even more mind-numbing, but go find the HTTP RFC (which is the document that describes how HTTP works) and read as much of it as you can. It is really boring but comes in handy once in a while.
    The most current,  HTTP RFC 7567.
  4. This will also be really difficult, but see if you can find someone to help you setup a web server like Apache, Nginx, or thttpd. Try to serve a couple of your .html and .css files with it just to see if you can. Don’t worry if you can’t. Web servers kind of suck.
    Tried without success to use Apache. :/ Moving on from now…
  5. Take a break after this and just try making as many different web applications as you can. You should definitely read about sessions in Sinatra so you can understand how to keep state for a user.
    A session:  a data structure that the application uses to store temporary information that is specific to the user. For example, after logging in, you do not have to login again on a different page. Or, you add some items to your cart, and go to the checkout page, your items are still in your cart. It’s like volatile temporary memory that is allocated to each user during their time on the site, and is destroyed when the user quits.
    A session is set up of key-value pairs. It’s like a hashmap where each user has a session id, that maps to their data (username, user_id, language, etc…). Each user is only able to access their own session in the session object. The session can be stored client-side(cookies) or server-side(session ids are created and managed by the server).  Here is a great article on how web sessions work.
    Summary
    In this exercise, I learned how to create a form and send the inputs with a POST request method. The post request method is how we get the web server to receive data. This method is usually used to submit forms and uploading files. I revisted the File object and its read/write methods to create an image upload. When a file is selected and uploaded, we create a new file in our images directory. Then we read the contents of the uploaded file object and write it to our new file.
    I learned about a new object class, Dir. We can use Dir to easily list directories and their contents. In this exercise, I used Dir’s glob method to return an array of all the paths to image files. Using this array, I could display all of the uploaded images on the page.
    These last few exercises are getting pretty difficult. I definitely feel a bit lost and overwhelmed!
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s