Getting De-railed

Anna's blog

Mastering Your Terminal -- Part I

Developers tend to spend a lot of time in their Terminals, and while most know all the basic commands to run, there are some that are less commonly used, but quite nifty to know.

In an earlier post, I mentioned that one can use command line to run a software update command: softwareupdate -l to see what updates are available:

Terminal, or more accurately, Terminal.app, is a terminal emulator program that provides a connection to your shell (most likely bash; run echo $0 to see what yours is running).

Technically speaking, running commands in Terminal is really running commands in a command-line interface that runs in a shell that runs in Terminal.

Now that we got that out of the way –

Some basic tricks:

  • Up or down key to navigate between commands. I use up all the time when navigating to a previously used command that is too long to type again.

  • !! to repeat last command (this will be specific to your Terminal window or tab in which you run it)

Ok, it is actually easier to press the up arrow once, but hey, saying bang bang out loud is a lot more fun.

  • Drop file name from Finder into terminal to get its path – it can be then copy-pasted into a cd command etc.

More ways to navigate Terminal using familiar shortcuts:

  • Ctrl + T to open a new tab within the same Terminal session.

  • Ctrl + F to search your Terminal’s tab or session (actual text output thereof).

  • Command + + or Command + - to zoom in or out.

  • Command + G to go to a next search match, Command + Shift + G to go to a previous match.

  • Control + C or Command + . to cancel a command. Rails developers use that a lot to stop Rails server from running, for instance.

  • Use TAB to autocomplete a directory name. Use TAB TAB to show a list of options when there are multiple matches.

Who am I, where am I, and what time is it anyway?

  • pwd to see user’s current directory:

  • whoami to see username of the owner of the current login/connection session in the shell (or in manual’s words, “display effective user id”)

  • While whoami is a very commonly listed command in all of the top-20-Terminal-commands-you-must-learn-now list, its cousins WhoAmI and who am i are less known:

(There is no manual entry on WhoAmI, and that seems like a pretty rare command in general.)

  • Another cousin who displays a more expanded version of who am i, effectivly showing all users that are currently logged in into a terminal session:

  • And yet another cousin w “displays who is logged in and what they are doing:

  • date to see current date and time:

How do I get around?

  • cd directory_name or cd path/to/directory to move to a different directory

  • TAB can be used with cd to autocomplete a directory name, but using an asterix (*) as a wildcard also works:

  • ?characters to search for a specific name:

  • cd .. to move up one directory, cd ../.. to move up two directories, and so forth.

  • cd ~ or just cd to go to your home directory.

  • cd / to go to the level of your file hierarchy (this is not the same as home):

  • cd - to go to the last visited directory:

  • Note on case sensitivity: generally, names of files and directories (so that cd octopress is the same as cd Octopress) are not case sensitive unless you have specially set up your system to be that way.

So what am I seeing in here?

  • ls to see a list of files in your directory (or ls directory/path for another directory)

  • ls -l to see a long list of files, including creation dates and access permissions, number of links in the item, etc:

  • ls -lh or ls -l -h (flags can be combined) to see a human readable output as long list. In this case, the only thing that changes is size in bytes is converted into units that make more sense such as kilobytes. Note that -h flag can be use with some other commands as well.

(Try running ls first, then !! -l, then !! -h to stack these commands. Or just press an up key and add those flags before hitting enter).

  • ls / (or any other ls command with a flag and /) to see contents of home directory. Note that normally, you have to be in the directory which contents you are trying to view.

  • du -sh directory_name to see size of a directory:

Rails Scaffold: Generating It, Deleting It, Evaluating Pros and Cons

Rails comes with a number of very convenient generators that can take a lot of work out of creating models, controllers, views, tests, corresponding database migrations, etc.

Like many other developers, I use Rails scaffold generation as an efficient and convenient time-saver.

From Guides:

A scaffold in Rails is a full set of model, database migration for that model, controller to manipulate it, views to view and manipulate the data, and a test suite for each of the above.

Of course, you can generate all of those components individually as well, depending on your needs. But I think the scaffold generator in particular gets quite overused.

A regular scaffold Terminal command looks like this: rails g scaffold Model_Name column_name:column_type:optional_index

Model_Name should be in singular, either under_scored or CamelCased.

Sometimes you hit the return button too soon, and deleting generated files by hand is just too much trouble.

There is a way to undo your entire scaffold: rails d scaffold Generated_Scaffold_Name:

(You can type out generate instead of g and destroy instead of d.)

Note that if you have already run rake db:migrate after generating your scaffold, the destroy command won’t work. It will delete the files that the scaffold command has created, but it won’t alter the schema and whatever alterations your migration has created will stay there. See my previous post on database-related rake commands to learn how to fix that (you will probably want rake db:migrate:down or rake db:rollback).

And assuming you do version control, to see if the destroy command left any files, run git status or git diff.

Realistically speaking, to create a scaffold that later needs to be edited (say, a new migration created etc – obviously a very common scenario) can cause more time-consuming bug-hunting than creating your MVC + other accoutrements from scratch.

To generate a scaffold with tests (default option) stops a developer from proper test-driven development practices: writing a failing test first, and then making it pass.

You can of course pass in an option to prevent tests from being generated when creating a scaffold. Run rails generate scaffold -h to see a list of options in your terminal:

The options above are for Rails 4.2.0 and might be quite different for your version of Rails.

You can see that the command comes with a variety of options that allow for reasonable flexibility. For instance, to skip generating a migration, you can pass in --skip-migration. To skip creating tests, pass in --no-test-framework.

Ultimately, once you know exactly what you are building to the extent that you end up passing in a lot of options, you don’t really need generators anymore and can create files manually that fit your needs. You wouldn’t want to use it for production. But if you are just learning Rails and experimenting with it, generators are very handy.

Rake Database Tasks

There are multiple db namespace rake tasks, which are very useful for a Rails developer.

I don’t often see them covered in Rails tutorials as a task list, and it took me a while to figure out which commands I needed to use in my regular workflow.


Migrations

Most beginner developers stick to rake db:migrate, rake db:seed and rake db:reset, but there are quite a few more options.

Migration is a version of a database (I still don’t understand what we are migrating and where, but oh well, such is conventional terminology).

Each new migration modifies a database schema (which starts out completely blank) by adding and removing data, changing data types etc.

Your schema is normally stored in db/schema.rb, although for some developers, it will be in db/structure.sql.

(To create and use structure.sql, use config.active_record.schema_format = :sql in your config/application.rb. Most beginners should be sticking to schema.rb, the default version.)


First, some schema-related rake tasks:

  • rake db:version - to see your current schema version. Schemar versions are normally also listed as timestamps, so you will see something like Current version: 20151014015045.

  • rake db:forward will push the schema one step up.

  • rake db:schema:load – loads she schema into your database. Good practice is using it when you first put your app in production; then run migrations from there on.

  • rake db:schema:dump – dumps she schema.


Now back to migrations:

The easiest way to generate a migration is to run rails g migration AddUseridToPosts user_id:integer.

Once a migration has been generated, it will be listed in your db/migrate folder, usually with a format datestamp_migration_name.rb. Running rails g generates a timestamp prefix because that is the order that Rails uses to execute pending migrations.

If you are creating a migration manually or copying over from another file, you need to use any alphanumeric prefix (even if it’s one 1,2, and 3) that allows Rails to run pending migrations in correct order; or use a manual datestamp if that’s what your other migrations use.

The migration in the example above adds a new colume of user_id, which is a type integer, to a table named Posts – assumption here is that one user has_many posts and a post belongs_to user (if you don’t know what that means, see Active Record Association Basics ).

You can generate a migration to add a new table altogether, to remove a table or a column, to change a data type of a column, etc.

Even if the migration is in your migrate folder, it does not mean it is in the database schema yet. To incorporate it into the schema, you have any pending migrations into it. And that’s when rake db:migrate task comes in.

Before I get started, see this rails source to see the database.rake file that describes exactly what each task does.

Rake tasks undergo changes between different versions of Rails, so it’s good to keep an eye out for anything that might be coming soon.


Rake migration tasks

  • rake db:migrate – runs the change or up method for all pending migrationsone by one in order indicated by name prefixes. If there are no such migrations, running the task won’t produce any outcome. But when there are, it also executes db:schema:dump as it needs to dump the schema and build it anew considering the migration(s) that have been added.

  • rake db:migrate VERSION=version_number/timestamp – runs specific migration to which the datestamp refers.

  • NB: rake db:migrate VERSION=0> – roll back all migrations

  • rake db:migrate RAILS_ENV=test – runs migrations in an indicated envrionment.

You should be able to get timestamp as a prefix to a migration file name if you used a rails g command as explained above.

  • rake db:migrate:up – runs up command for a given migration version (default is current version)

  • rake db:migrate:down – runs down command aka rolls back command for a given migration version

NB: Up and down are actually old-school commands; up makes a change to the schema and down reverses the up change.

  • rake db:migrate:redo – “Rollbacks the database one migration and re migrate up (options: STEP=x, version_number/timestamp).”

  • rake db:migrate:redo STEP=x = rolls back x many migrations and re-runs them

  • rake db:migrate:rollback – roll back last migration to get user back one step.

  • rake db:migrate:rollback STEP=x – roll back x many steps

Now this is interesting:

  • rake db:migrate:reset = rake db:drop + rake db:create + rake db:migrate = undo and re-do migrations again for current environment. It does not rollback migrations. You would want to use it when, say, running rails destroy scaffold Name as it will remove a corresponding migration and the schema would need to be re-created. You would still need to run rake db:seed if you have any seed data.

(rake db:create is rather straightforward and an opposite of rake db:drop; it needs to be run when a Rails project is first created or after a database has been dropped, as it the case with rake db:migrate:reset above).

Note the difference compared to:

  • rake db:reset = rake db:drop + rake db:setup

where

rake db:setup = rake db:schema:load OR rake db:structure:load + rake db:seed

  • (rake db:schema:load loads schema.rb into your database)

  • (rake db:structure:load loads db/structure.sql if you have specified that in your config, otherwise it will load db/schema.rb)

Which means that rake db:reset drops the database; recreates it from db/schema.rb or db/structure.sql in your current environment (and NOT from migrations); seeds database from seeds.rb. Note that if you have had anything imported into your database from, say, a csv file, that content will also be gone.

  • Note that rake db:migrate:reset won’t seed your database and rake db:setup will.*

Another rake task is also useful to see where you are with regard to migrations:

  • rake db:migrate:status – display status of all migrations. It will alert you if there are no schema migrations in your project yet.

And a heavy hitter to get you re-started with a clean slate:

  • rake db:purge – “Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases.”

(The rake db:purge task was only added in January 2014 and is less known.)


There is a great Rails Guide explaining a lot of these here.

Remember to restart your rails server when working with these.

Should these tasks not meet your needs, you can always create a custom rake task to do exactly what you need.

Making Custom Rake Tasks and Using Them With ERD

I started making my own rake tasks recently to help with specific repetitive tasks that I need to do while working on projects.

Rake is a project of Jim Weinrich; check out his rationale for making rake here.

My favorite part is his explanation of why it is called rake. No, it has nothing to do with garden tools. It was supposed to be a portmanteau of ‘ruby’ and ‘make’ (since Rake was inspired by Makefile). Hence, rake.

rake -T will give you a list of rake tasks available for a given project.

This is what it looks like for a standard octopress directory:

So if I forget that my normal routine is rake generate followed by rake preview, I can see it listed above.

I was working with the erd gem, which uses Graphviz to visualize complex database relationships in rails. If you want to understand what exactly is happening in your schema, it’s the gem for you.

I haven’t used it in a bit, so I googled it, and this tutorial popped up.

It had a suggestion to make a simple rake task to run the erd command with specific attributes to get just the type of a diagram you want:

  task :generate_erd do
    system "erd --inheritance --filetype=dot --direct --attributes=foreign_keys,content"
    system "dot -Tpng erd.dot > erd.png"
    File.delete('erd.dot')
  end

The idea there is have a task that runs erd --inheritance --filetype=dot --direct --attributes=foreign_keys,content. The system then generates a .dot file, which is when converted into a .png file, with the rationale being that Graphviz has issues generating files that are not .dot.

You can just put it in a rake file, or run rails g task erd generate_erd. It adds a erd.rake file to lib/tasks (or you can add one manually and just type your code instead of using a generator).

To use that task, you type rake erd:generate_erd in your Terminal.

I ended up using these rake tasks to demonstrate the idea behind using namespace. They generate a png file as per an example above and a default pdf one:

And running these tasks in Terminal:

And you are done! Two file types of database schema charts have been generated:

NB: if all you wanted was to simplify running one long command (such as the aforementioned erd --inheritance --filetype=dot --direct --attributes=foreign_keys,content), you could just create a shell alias that you could then use across all your projects if they have erd installed.

Mac Uptime and Reboot Stats

While we are on a subject of controlling your Mac from your Terminal, here is something else that is useful:

Mac uptime is how long it has been since the system has been re-booted or re-started. Type in uptime in your Terminal, and you will see the stats in minutes, hours, or days, depending on how long it has been for your Mac:

(I just re-booted when installing a new OS X hence such a short uptime for me. Uptime can extend into months for some users as Macs tend to be very stable unlike Windows machines.)

You will also see number of users using your machine during said uptime as well as load averages in 1, 5, and 15 minute intervals from left to right – mine actually indicate I may want a more powerful system.

Run last reboot to see rebooting history:

Another neat trick is to run in last to see last sessions of users, hosts and ttys in a reverse chronological order:

There are handy gadgets for uptime and reboot stats, but I doubt that most regular users would really need them on a regular basis. Checking in with your Terminal now and then should be sufficient.

Updating OS X From Your Command Line

I am really used to seeing a pop up that says something along the lines of a new version of OS X / iOS is available, do you want to update now?

Upon some research on potential issues of an update in question (I learned the hard way after having my iPhone bricked post-update when living in China), I generally go back and click update. But there is actually an easy way to do it from your Terminal. All you need is a softwareupdate command.

Type in man softwareupdate to see this command’s manual:

Run softwareupdate -l to see available updates. You will see something like this:

While you are at it, you can turn on automatic update checker from your Terminal: sudo softwareupdate --schedule on (off to disable it).

Then run this to install the specific update you want: sudo softwareupdate --install UPDATE_NAME

(Use the -d flag to just download the update, but not install it.)

And of course to re-boot your computer, you can simply run this command instead of going through the Mac menu: sudo shutdown -r now

Voila!

Running Edge Rails -- Living Dangerously

Rails is constantly being updated and improved. Sometimes, the changes that have been announced are just too exciting to wait for an official release.

When I first read about ‘Edge Rails’, I was quite confused because it sounded like yet another JS library. Then when I was reading The Rails Way (Amazon link if you have somehow never heard of it), I realized I had been mistaken.

Grammatically speaking, it should be spelled edge Rails, as in lowercase e. But that is really between you and your text editor. In this context, ‘edge' just means the latest, cutting-edge version of Rails that has not been officially released yet.

Rails 5 looming upon us, but there is no official release date. I gather the best guess is late 2015 — early 2016. It does have some exciting features, such as merging of the rails-api gem / built-in support of the JSON APIs). So what do you do if you want to play around with that and don’t want to wait until the official release?

Ruby -v to see if you are using ruby 2.2.2+ as Rails 5 requires it. Use rvm to make sure you are running a suitable version.

The best instructions to install edge Rails can be found here on Christopher Bloom’s blog — they are straightforward and and I used them successfully, so I’d rather send you to the source than to copy-paste them here.

RailsGuides has an EdgeGuides section specifically targeting the current master branch of the Rails repo.

Running edge Rails comes at a cost of potentially unstable dependencies. Having said that, it is not that unstable. Rails has a very extensive test coverage, which should help prevent regressions.

So do you want to run edge Rails? Probably not, unless you really plan to take advantage of groundbreaking unleashed feature or if you are particularly curious. But it’s nice to know it’s there.

And the New App Is Done

Behold – a real app!

We used meteorological knowledge to convert weather forecasts into a ‘real-life’ weather forecast. It takes into account humidity and wind speed for a variety of different scenarios to tell you what will it actually feel like outside in the next 36 hours. Some days, it will feel colder / cooler than what the weather forecasts say, and some days it will much hotter / warmer.

This was really fun to work on, and I really enjoyed making something useful – I have been using it every day to make sartorial choices and to figure out best time of the day to run outside.

And it’s sassy.

Project Mode -- Week 1, Day 2

…and we are officially in Project Mode here at the Flatiron School, working on project 1 of 2, which is meant to be a short project to be conceptualized, pitched, designed, built, and presented within a scope of 5 business days.

Here is a very short video showcasing functionality that we have built in 2 days. We have deployed to Heroku since the video was made, which turned out to be much easier than expected, minus some fiddling with the Figaro gem.)

Primary goal right now is to make it aesthetically pleasing.

It looks fairly simple, but it actually features some pretty advanced weather-related logic. Who would have thought that energy trading background would come in handy.

On a Scale of Dalai Lama to Kanye West, How Narcissistic Are You? A Rails App That Lets You Find Out Just That.

For a small side project to be shared with our Flatiron School classmates and some Flatiron School Presents Meetup guests, my partner Mitch and I decided to build an app that measures people’s narcissism levels via their Twitter feed. A linguistic analysis-baased social insights algorithm, if you will.

(meme taken from here – spoiler alert for celebrities' narcissism levels)

Much has been said and done and invested into when it comes to social media sentiment analysis in finance, with many financial institutions investing heavily in it. A cursory Google search offers up names of many start-ups involved in mining, mapping, analyzing, and plain having fun with Twitter. We figured that as tech professionals, working with social media and building a fun prototype for understanding the tools and the medium is a valuable experience.

Our original idea was parsing through people’s Instagram feed to see how many posted photos were selfies for a better narcissism indicator, but considering advanced facial recognizition technology needed and the fact it was meant to be a small side project executed while carrying on a full school work load, we have settled on the twitter-based project.

The Twitter gem made working with Twitter a breeze, although there were limitations for how many posts could be parsed through at once and of course the max number of timeout requests every minute.

We designed everything through the use of good ol' Rails New NarcissismProject. We had one user model that we worked with.

The front page invites a user to check how narcissistic the are by entering a twitter handle (which will work whether or not prefixed with an @ to make user’s life easier; we have also allowed for the first or last typed character to be blank space in case a user is very space-key-trigger-happy; other than that, the handle has to follow Twitter rules as ensured by a RegEx check):

Once a user enters a twitter handle, it parses their feed for key narcissism-related words that we have pre-determined in the app; it then checks it against a scale of celebrities. It then returns user’s score and their celebrity match (mine is Flatiron School’s very own Avi Flombaum)

We don’t share the celbrity scale on the app, as it is more fun for the user to discover it him/herself. To built it, we have parsed through the top 100 most-followed twitter accounts (most of which are individual celebrities) and some more and scored them. We then picked some representatives for each scale gradation, throwing in a few Flatiron School-related Easter Eggs, just for fun. If this was a commercial product, we would have to update the celebrity scale just in case some of them go into narcissism rehab or new self-loving celebrities merger.

Most of our findings were unsurprising: Dalai Lama and the Pope were at the very bottom (with Dalai Lama being slightly less narcissistic and thus representing no. 1 on our scale); Kanye West was 9 out of 10 (beat only by the likes of Lena Dunham); Mr. West was closely followed by Kim Kardashian in the 8th place. To me, this means that are simplistic prototype algorithm actually works!

I stopped to pondered if it is unethical to make fun of people’s narcissism levels, but considering the celeberities that came up on top and their interest in self-promotion, I figured out their high tankings it would be quite a compliment to them (I am really, really tempted to tweet Mr. West and ask him how he feels about being outdone by Ms Dunham).

What turned out to be incredibly fun was soliciting our friends' and classmates' twitter handles and checking their narcissism levels. A few were truly off-the-charts! (We even had to design more model logic for those cases) The top 10 narcissistic twitter handles are then saved separately and published on the Top 10 page – with many people I know outdoing our celebrities of choice. Uh oh.

A short demo video can be found here – YouTube link.

And here is a link to the Github repo.

I will update this post once the app actually goes live as is our goal.