#ruby, #rails, #OOP, #javascript, #ember

Showing posts with label ruby. Show all posts
Showing posts with label ruby. Show all posts

1/25/17

Setting up Polymorphism in Ruby on Rails

Polymorphism can take a little longer to understand conceptually than other topics in OO. It is an abstraction which takes a little more effort for the developer to implement, but makes extending easier later on.
In this example I have three models that I want to add an attachment too: Patient, Prescriber, Order. Each attachment requires the same attributes and instead of adding a new attachment column on each model I am electing to create a new model called "AttachmentObject" and make it polymorphic. I am using the paperclip gem with S3 for attachment upload.
class AddAttachmentPolyObject < ActiveRecord::Migration
  def change
    create_table :attachment_objects do |t|
      t.string :title, null: false
      t.references :attachable, polymorphic: true, index: true, null: false
      t.attachment :attachment, null: false

      t.timestamps
    end
  end
end
class AttachmentObject < ActiveRecord::Base
 belongs_to :attachable, polymorphic: true
 validates :title, :attachable_id, :attachable_type, presence: true
end

then for my relationships to my "attachable" models (Patient, Prescriber, Order).
class Patient < ActiveRecord::Base
 has_many :attachment_objects, as: :attachable
end

class Prescriber < ActiveRecord::Base has_many :attachment_objects, as: :attachable end
class Order < ActiveRecord::Base has_many :attachment_objects, as: :attachable end

It is not necessary to name your "has_many" relationship with a name that uses "able" as a suffix, but you will see that it is a popular amongst rails devs and you should use it as a convention when possible. Now comes the fun parts. With my AttachmentObject I can now use rails helpers to find its related attachable parent. Active Record does this by looking up the 'attachable_type' (which points to either Patient, Prescriber, or Order table) and 'attachable_id' which points to a row on the table. for example:
#explicitly
order = Order.create( valid_attributes )
order_attachment = AttachmentObject.create(title: "phish", attachable_type: "order", attachable_id: order.id) 

#or implicitly
order_attachment = AttachmentObject.create(title: "phish", attachable: order) 
I can then do
phish = AttachmentObject.find_by_title("phish") 
phish.attachable #returns the related order_attachment

12/20/16

Cacheing Ruby With APICache gem

If you're running a rails app then chances are you're playing with multiple apis. This week I found myself working with the robust JIRA api so that I could return worklogs and do something meaningful (and more user friendly) for a client.

You could easily write your own cacheing class using timestamps and urls as keys for the queries, but I really like this gem (APICache by Martyn Loughran) because it has a couple nice features out of the box like :period, :valid, and :cache timeout options. The gem is also simple; it consists of two main classes, Api and Cache, which are both under 100 lines of code. The other few classes are wrappers that help you configure your 'mem-cache' store which we'll get into later.

First download the api_cache gem Then add 'config/initializers/api_cache.rb' And add this code
if Rails.env.production?
  APICache.store = APICache::DalliStore.new
end
This will set up a dalli store (which is a pure Ruby client for accessing memcached servers) when you are in production and will use memory to cache data when running locally. This allows you to boot up your app and play around without having to run a second server every time. When you get ready to deploy to production read the Dalli docs to learn more about how the process works.

In my example we are retrieving large data sets. Returning the JSON and refreshing the page took around 15 seconds, no bueno. In order to cache all our request to the Jira server we used our own wrapper class that defined a 'get' method. This class inherited from our jira::client so that way all gets would go through our logic. If we want to implement a new http request (like put, patch, post) we can follow the same pattern. We then wrapped our get method with APIcache logic
  def get( url )
    APICache.get(url, :cache => cache_timeout, :timeout => 15) do
      super(url)
    end
  end

  def cache_timeout
    skip_cache ? 1 : 3000
  end
The skip_cache is an attr_accessor which we pass in when we instantiate this class on specific situations. Besides that we use our default cacheing timeout setting which is 50 mins.
The Api Cache gem also allows these configurations 
{
  :cache => 600,    # 10 minutes  After this time fetch new data
  :valid => 86400,  # 1 day       Maximum time to use old data
                    #             :forever is a valid option
  :period => 60,    # 1 minute    Maximum frequency to call API
  :timeout => 5     # 5 seconds   API response timeout
  :fail =>          # Value returned instead of exception on failure
}
Check out api_cache gem for the official docs.

11/23/16

That's not broken... Re-think your design

It has been 9 months since I have posted on this blog and I have learned a TON in that amount of time. I'm restarting this blog to share some a few things I learn each month. To start off, here's some Devise.

We have all used the very popular Rails engine ‘Devise.’ A couple weeks ago I came across a new use case with the gem about overriding one of their standard methods. I was dealing with the mailer and a client wanted to redirect to a new page after a user confirmed their account via email. Simple enough. The problem was my agency uses a custom rails engine that preinstalls Devise and therefore some of it's initial configuration; like overriding the 'after_confirmation_path' method.

First I tried overriding Devise's method just like their docs suggest, but that didn't work for some reason. Maybe I source the gem from my local (instead of rubygems.com) and update its child method 'after_confirmation_path' to fit my needs? That could work if I was doing some serious customization to the overall gem, but I clearly was not. I also tried setting the Devise mailer to use my own mailer in its configuration. No luck.

Then I considered calling the 'grandparent' (which would be the devise method) and overriding it for the project I was in. Apparently this is a thing, but there was no way that it felt right for doing something so simple. This was my first hint that I was on the wrong track. (stack overflow dealing with grandparent override). I also tried setting our custom gem's mailer to use my own mailer in its configuration. No luck.

In the end, the solution was a simple configuration that I had overlooked. I'm currently learning Ember.js and I stumbled upon this quote the other day that relates to my problem here: "It sounds like right now you're working hard to do something that Ember deliberately discourages. Generally I find when I'm fighting the framework it's because my understanding of the problem is different (and often not as complete as the framework authors)."
Devise.setup do |config|
  config.mailer = 'UsersMailer'
end

The lesson here: Pay attention to signs that you are on the wrong path and moving too quickly. When solving simple problems look for simple solutions. Don't reinvent the wheel. I should have spent more time looking at my first solution instead of dismissing it and thinking there was something wrong with my apps design, or Devise.

Here's the end product, which Devise easily points to in their docs
class Users::ConfirmationsController < Devise::ConfirmationsController

  protected

  def after_confirmation_path_for( resource_name, resource )
    super + "?email=#{params[:email]}"
  end

end

1/13/16

Resume, LinkedIn, Portfolio and Updates from this Week

Past few days I have been all over rubymonk.org, Lynda.com, guides.rubyonrails.org, Rails 4 Way (3rd edition) and some treehouse videos. I also have a portfolio page up here, updated resume, and linkedin ready to go.

I never considered myself to have attention deficit disorder until I began to learn to code, not because I constantly struggle with looking at my phone or scrolling my FB feed, but because of the sheer amount of things I want to learn it's hard to decide where to focus my attention. I have decided I am going to finish the month of January out strong and begin seriously looking for work in February. In the mean time I am continuing to practice ruby, study rails, read everything I can, and see if I can find some freelance or open source projects that I can contribute to.
White Board | Check List | Recent Goals

Here a summary of the past few days:

Ruby Monk-- Finished ruby primer and am 2 1/2 chapter into Ruby Primer Ascent. I have found this site very helpful with brushing up on things I have forgotten and also teaching me a lot of new things about the way Ruby works. New things I have learned include: converting implicit blocks to explicit, how a class instance variable can be beneficial, the difference between puts and p, and how to use the splat method.

lynda-- finished RSpec course and have a good grasp on how the framework works and why it is so important. Learned how to write model specs (usually the most important specs), helpers, controllers with the HTTP requests, and views.

RubyonRails Guides and Rails 4 Way-- I have spent a few hours today reading over how routes work and was amazed at how it really cleared up a lot for me. Even though I have been feeling good about rails this was super helpful to be reminded about HTTP and route names and how 'resources :name' works.

Tree House-- signed up for a trial (I know, getting spread thin) but am really interested on their take on how ActiveRecord works. I am currently finishing up their Database Foundations tutorial working with sqlite and Work Bench.

When I first decided to learn to code I was attracted by the lucrative salaries and job security. That part of the industry seems less important to me the more I learn. In the past five months I have developed a different way of interpreting things and that is really rewarding. It's amazing because I have been putting in long hours (10-12 hours a day the past 8 days) and am genuinely enjoying the process. My focus is on being a great programmer and I have never felt better.

-John

1/9/16

Great expect(ations) w RSpec

The holidays are over an I have been chipping away daily. This week I have dedicated much of my time to learning RSpec and testing ruby frameworks. Searching around there isnt an abundance of testing information for beginners on the web, but I signed up for a free trial at Lynda.com and have been very happy with there 6hr class on testing with RSpec. I'm about 3/4 finished and have learned much of the syntax and theory behind RSpec.

If your learning Rails you should learning some sort of testing. It may not be necessary in the beginning, but you will need to have it in your tool belt when things get a bit more complex. Also, I feel that if you wait too long to learn testing it could become a bottle neck in your growing progress.

Also, I can't recommend Lynda.com enough. I have only viewed their course on testing ruby frameworks but I have a feeling that everything they do is at a high level. I plan to continue to use them as I move forward.

Here is a summary of what I have learned the past two days with Lynda and RSpec:

The hiearchy is important: spec file => example groupe => nested group => example => expectations is really the meat of the whole operation and once I understood that I really started to understand the big picture.

Helper methods: It is important to keep your suite as fast as possible therefore encouraging frequent tests. Now this is a non issue for small projects, but as things grow I could see how this would slow things up. Helper methods help keep unnecessary tests from running and slowing down the process.

The let method is really cool because it creates a helper method that takes one argument, which is the name of the method you want to create and then a block of code.

ex.
let(:car) { Car.new}

it "allows reading for :wheels" do
  expect(car.wheels).to eq(4)
end

you can also use subject as your helper

ex.
subject {Car.new}
  it ....
end

........and going farther you can define subjects implicitly by using a class name as the 'describe' argument

ex.
(this is how it looked like before)
describe 'Car'
  subject { Car.new }
  it ....
  end
end

*is the same thing as

describe Car
    it...
    end
end

^Here the subject is implicitly defined. As soon as it encounters the class as an argument it creates a helper method with the subject as the class Car. this works well if the subject you are working with is in only one class.

For Rails testing I learned about SHARED EXAMPLES, which is where RSpec begins to get more complex.

Shared examples let you describe behaviour of classes or modules. When declared,
a shared group's content is stored. It is only realized in the context of
another example group, which provides any context the shared group needs to
run.

In rails this comes in handy when describing things like 'CRUD' in your controller.

ex.
describe ProductsController do
  describe '#index'
    it_behaves_like 'a standard index action'
  end
  describe '#new'
    it_behaves_like 'a standard index action'
  end
end

.....and so on

Should be finishing up the rest of the course tomorrow along with the last touches on my portfolio and resume. I'll be going to a meetup this next Thursday at Hashrocket in Jax Beach, and they give opportunities at the end for attendees to put projects up in front of the group to have it "torn a apart" by the pros. I hope to have a TDD or BDD app built from the ground up by then; I'd love to get live feedback that way.

it is now 4 a.m., please excuse the typos

-John

12/28/15

Tech Talent South Complete, Now What?

Outside of Class
Learning to code is a journey. Let me first acknowledge that I am not at the end of that journey, and I that is a good thing because learning to code is a process, not a means to an end. Looking back, everything that I have learned at TTS over the past 8-weeks is amazing and I am beyond thankful for the opportunity. Last night I was going over my personal notes from the first week and it feels great seeing where I was then and where I am now. Over the course of this class I have built over 30 apps, learned git, github, Ruby, Rails, JavaScript, HTML, CSS and even a few things that werent on the lesson plan such as testing.

Of all the cool things that we did during class, my favorite and most rewarding would definitley be our final project that two classmates and I completed during the final weeks. We were told to make an app using the things we had learned in class; no guidelines. While brainstorming we decided our favorite thing about class was working with api's, so we looked around the web and found some we liked. We eventually choose a weather api and an event api. Two weeks of wrestling with our code we created Drink Weather, a silly web app that takes a users current location and returns the current weather, an adult beverage recomendatioin based on that weather, and also an activity according to weather and location. Working from scratch really helped cement what we had learned throughout class and the all the mistakes that were made during our creation of Drink Weather made us better coders now. We also became very familiar with working on github as a team, and how to deploy a rails app to heroku. I know it's not perfect, but we all took pride in the creation of Drink Weather.

TTS is now completed and here are the next things on my agenda:

  • Test, test, test. Pretty much every dev that I have had the pleasure to talk with over the past month has mentioned the importance of testing which is one of the areas that TTS did not cover in depth (we only spent one day on testing and really only provided a basic introduciton). I understand why it is important and know I will need to be comftorable with the practice in order to land a job. 
  • Learn VIM- I know that there are mixed opinions on vim, atom, sublime, etc. but after talking to some pros it does seem that learning vim could really improve my proficiency and help with job placement.
  • Sharpen my Ruby- I am most familiar with Ruby of all languages with JavaScript coming in second. When getting advice from people in the industry, one of the things I was most interested in was whether I should focus on learning one language really well or spread my self out and learn the basics of a few languages. Most people said to get really good at Ruby first which will not only help with a job but also with the process of learning a new language in the future.
  • Sharpen JavaScript- Like Ruby, I am familiar with JS and want to continue to improve on it. 

I officially quit my previous job at the end of August and aimed at securing a job within six months. That means I will be employed be the end of February, wish me luck.

-John

11/9/15

Tech Talent South Week 2 Update

Tech Talent South has greatly sharpened my understanding of many programming basics I thought I had already mastered. It has only been two weeks with the program and  I cannot not over emphasize how great it is to have an instructor to bounce questions off of. TTS runs four days a week, four hours each class and two extra office hours each day. So far we have covered the basics of Ruby (arrays, methods, hashes, and Classes), which I had studied when I first began to learn in August by reading Chris Pine's book, "Learn to Program". It was a good refresher on the Ruby language since I had not done anything with Ruby since I read Pines book and I also enjoyed being around other students during the learning process. I have also found it valuable to see how others work out the problems as they go; it ultimately helps me think about problems in different ways, something I could not duplicate working on my own most of the time.

Last week (week 2) we got into Rails which I was really excited about since this was essentially uncharted territory for me. I remember just starting out I wanted to try rails after finishing some ruby stuff but gave up after an installation fail. lol. Thinking back to that point I remember being overwhelmed with all of the information out there and not knowing where the hell to go. Being in this program really helps with that. Now I have a set curriculum with an instructor leading the way to help out when I get hung up on something.

This weekend I started going through the Ruby on Rails Tutorial by Michael Hartl, which is a great supplement to what we are doing in class. I have gotten through the middle of Ch 3, which is basically what we have accomplished in class up to this point. I have to say that going over this book after the work we do in class really helps me understand the concept of rails and how the MVC framework functions. In my own words, when you type something in the browser that then goes to the rails router and requests that page from the controller with the same name. That then, using instance variables, goes to the model which retrieves the information from the database, returns that to the controller which then goes to the view page, renders the html back to the controller and to the browser...and boom, web page.


We created some small rails apps so far including a mock university which uses a database to store classes, students, grades, and depatments. I have gotten a lot more familiar with the command line as a result of using rails as well as a general knowledge of git and heroku. I'm really excited to see what I can get my hands on this week as I continue to further my learning in and out of the classroom.

-John

8/13/15

Laying the Ground Work

Background

I am a 24 year old college graduate from Jacksonville, Florida. Since I was 15 years old I have held a job. Through college at the University of North Florida I supported myself bar-tending at a wing restaurant on nights and weekends. After graduation I decided to take some time away from the rat race and moved to Jacksonville beach with two close friends. During this time I spent much of my time in the public library "finding myself" as I knew I was not satisfied with working in a restaurant for the rest of my life. I soon landed as an entry level sales position (the thought being anyone who bar-tends and works in the service industry will naturally do well in sales). Although I found myself highly capable in my new position I was also unhappy; I did not enjoy the work.

After more searching and logging more library hours I soon discovered computer programming. Two things jumped out at me right away. First, anyone can learn it no matter what your educational background is, and two, coding and literature (or reading and writing) have many similar characteristics. I started thinking that not only could I do this, but I could excel at it.

Fast forward to today and I have completed one course on codeacademy (Ruby), two courses on lynda.com, and have finished Chris Pine's book Learn to Program along with much research. I know I have a long way to go but my excitement level has only grown the more I learn--a good sign I believe.

I recently moved home with my mom and dad to Middleburg, Fl which is great because it removes me from distractions that I would be surrounded by if I lived near downtown Jacksonville or Jax Beach. I also have an open invitation to live with my older brother in Orlando, which I will certainly take advantage of for networking events like meet ups and conventions (there is zero tech presence in Middleburg, just woods).

Goals:
(clock starts 8/21/15)
· Secure a computer programming job in SIX months. Important because it will help me become financially independent and prove that I have what it takes to set a challenging goal and reach it. I will fulfill this goal by working 60 hours a week (10 hours a day) learning to code, going to networking events, and building my portfolio.

· Read a book a week. I'm a complete nerd when it comes to education; I think it's pretty neat. And I also believe that it is important to be well rounded so that I can create value in myself. I will read one book not related to coding a week. These books will be diverse in subject (philosophy, economics, self improvement, writing, etc.). I will accomplish this by reading two hours before bed each night.

· Get in great shape. This is important because the body and mind work in concert together and if one is out of tune it will influence the other. I will jog every morning starting with a mile a day and do strength exercises for 20 mins in the evening. I am keeping this very simple as I am more concerned with building a habit of exercising than following a strict regiment. I fully expect the distance and time of exercise to increase over time.

Simple Rules
(Influenced from the Stanford Entrepreneurial Podcast. There is an article here.)

· Wake up at 6 am every day

· Plan tomorrows schedule the night before

· Reach out to one new person in the tech industry daily. (twitter, email, linkedin, etc.)


Let the Games begin!

-John

8/12/15

In the Beginning...

Why should anyone learn to code? For me it comes down to investing in an education that makes sense in today’s ever evolving technical world. When I was searching for a degree to major in during my first couple of semesters in college I generally took the attitude that I should study the things that I enjoyed the most, and, in theory, a profitable job would follow suite. I choose to study English literature and if I could go back and do it again I would not necessarily change that. For me, the education I received from studying figures like Henry David Thoreau, Alan Watts, and James Weldon Johnson was monumental in my development as a person. The thirst for more of the things that we studied in class became desire that I could not quench, and to this day I spend much of my free time in the public libraries throughout Jacksonville.

I would, however, lower my expectations of the exchange value a liberal arts degree merits from others, primarily future employers. Perception is reality, and education is only as valuable as that reality.

My goal since my sophomore year of college was to go straight to law school after graduation. That began to change once I started to research law schools and began debunking many of the myths that surround the coveted JD. After speaking with attorneys, professors, and current law school students, I realized three things: One, practicing law is nothing like what you see on T.V.; Two, the financial investment of a law degree can be crippling-- forcing graduates to work in environments that they hate simply to pay back what they owe in student loans; And three, I realized that many of the graduates passing the bar exam are another two or three years away from actually knowing the ins and outs of the law game.

After taking a "pause" after college, I began to search for a career I could fit into, and like many other college graduates, I had no idea what I was doing.

A few months ago a friend of mine introduced me to the website codeacademy.com and told me to give coding a try. I began on the “Ruby” course. My curiosity rose. The next day I researched the mass influence that computer languages have on our world and its potential impact on the future and my curiosity turned to intrigue. People say there is a moment in our lives that wakes us up; an awakening of sorts. A moment so significant it's like seeing the world for the first time. This was not that moment for me. In fact, I envy those who experience sudden "aha!" moments that change their life around in an instant. For me that has never been the case, however, the introduction to Ruby was my very first step in taking control of my future and making a decision to enter the tech world.

"A real decision is measured by the fact that you've taken a new action. If there's no action, you haven't truly decided." -Tony Robbins

I have officially taken action. In early August I gave my two week notice to my employer and agreed that the 21st would be my last day. Since the middle of July I have been researching the proper path for a self taught programmer and I have been overwhelmed with the amount of information out there along with the amount of people in the community that are willing to help. Simply put, I can't wait for the 21st to come around so I can begin this journey full time. Until then, I will settle for nights and early mornings.

Today, as I write this, I am taking action for a better future. Creating this blog, investing in my self education, and learning a computer language are all steps that will help me reach my goal of securing a job in the tech industry.

-John