Wednesday, 31 December 2014

The Asset Pipeline for Rails

Today, while I was trying to find out why my coffeescript files weren't running on a Rails project, I had the wonderful opportunity to just dig in and read through wonderful documentation on the Asset Pipeline.

It's incredibly helpful and informative, because it made me understand how exactly Rails will percieve the Assets folder that is so crucial to a lot of our projects. In particular, how it reads into the folders, how to customise it, how to specify which asset to use in your html.erb files and more.

Definitely worth my time. Who knows, it might help me figure out -why- my coffee.js isn't being read, it might not - but all the same, the knowledge is crucial.

Also: HAPPY NEW YEAR!

Monday, 13 October 2014

Venturing into Node

The last week, I've been digging into a few codeschool tutorials on node. Node is, from what I gather, rapidly gaining popularity (if it hasn't already), and has some tremendous capabilities. In particular, it is very fast, and I hear astounding news from people that say it's about as close to just parsing code in C speeds as you can get.

That's pretty impressive, when considered. That said, It was a choice between Node or Angular.js (Or perhaps even Ember, or Meteor), but I decided to go for Node first.

Installing it was fairly easy, and the tutorials introduced me to Express, Socket.io, and a new database record (with some -very- simple setup and commands!), Redis.

I'll be putting up some code down here as I get more and more into it, for the time being the syntax and getting over the incredible amount of braces used in node still kind of throws me off, but I'm getting the hang of it.

Thursday, 2 October 2014

Making Highcharts Series from ActiveRecord items

Following up on the previous blog, where we successfully linked categories on the X-Axis with an Active Record table, we'll move on to the next step, that is actually taking data to be used and displayed on the Y-Axis.

But first, a few things:

The method I described the other day to iterate through all ethercraft names in our controller is actually not necessary. Someone (thank you!) pointed out to me that a method does exactly what I was doing already: .pluck.



So instead of above, in the controller action where this method was called I just did:


@ethercrafts = Ethercraft.pluck(:name)

And I can safely remove this method and all.

Next, we'll need to make sure we can actually get data for our series. In the previous example, we used a census to obtain the number of people practicing a certain ethercraft by country. So, we'd need to make sure that we can link countries generated via ActiveRecord in case we add/remove more countries.

Let's change this a little (because I already have Race set up as a selection for characters) and make our graph just draw a census of number of ethercraft practitioners by race. We just need to make a race table, along with the associated actions to add/edit races in the app with the actions, and it'll be fairly similar and ready like ethercrafts.

Now, the challenge next is finding the data we need to actually add the series and have actual values for the graph itself.

If you recall the format for generating series in highcharts:






The series itself is expecting:
  •  An array, that contains
    •  hashes for each series, with each containing key/value pairs of
      • a name for the series, and
      • data, which contains
        • an array that contains counts for each category on the graph
Keeping that in mind as we make our ethercrafts-by-race census, we'd need to have a hash for each 
race that has data for how many of that race practice an ethercraft.

But since we live in an era of databases and charts and linked information pulled from repositories, we'll generate that data ourself.

In this sandbox app, a fantasy character generator, I've got characters, and each character has a race, and an ethercraft. To make this data count work, I'll link characters to their race and ethercraft choice in ActiveRecord via foreign keys. Each character belongs_to one race and belongs_to an ethercraft.

Once that was done, the next step was very simple: to generate the series, we'll just need to add to our controller a new method that'll iterate through characters, iterating each ethercraft for each race.


This method, defined in the controller will take all races and ethercrafts and iterate through each ethercraft for each race, finding characters that meet the current race/ethercraft combination. The glory of map is that, when used in this way, it generates an array the way we want it to. It creates an array for the counts for ethercrafts in order of their id, and fixes them into the race_ethercraft array for each race. At the end of the ethercraft map, it makes a hash taking the current race's name and the array generated for a data key, then that is automatically added into an array for the results for mapping the races. Once that's all done, we'll have every race with a hash that has the numbers we're looking for.

Now all that's left is to fix up our HTML and our AJAX file:


AJAX:



And we'll boot up our chart again:


Presto! Of course, this was made after I quickly rigged up a bunch of characters in the database, and even then - it still looks empty. But if you had real data to add from a database, this would be one way to do it.

The issue arises, that I can think of is in how that method was written: assuming I had a lot of data to go through, would the chart load as quickly? One way to find out is to actually get a lot of stock data. And that's something I'll look into for next time.

Hope this helps, and as always, comments and critiques are appreciated!

Tuesday, 30 September 2014

Passing raw array variables from Rails to JS to HTML

I was working on highcharts to follow my previous blogpost, and I got the chart to work. That's great, but highcharts is incredibly flexible and has a lot of features one can use to create dynamic and interesting charts.

But to actually get there, I need some data beyond static example data of John and Jane eating fruits. So, I worked on passing PSQL database objects into the AJAX file in Rails, so that I could apply the variables I want into the chart. How and why would someone do this? It's fairly obvious why, but an example would illustrate things a bit better.

The chart is merely an example; there's many situations where one would want to transfer a database item, or value, or anything into their AJAX file, but that's moving things from Ruby to ERB to JS to HTML. The core issue to keep in mind is to keep the object being passed around readable all the way.

In this case, we'll make a chart that depicts a census of people with different jobs in different countries. In this fantasy fiction world, we'll call them ethercrafts to describe how they cast their magic spells in their day to day. There are 2 countries in this example, Zahnheim and Rogalia. The end result is to look like this:



There's 5 different ethercrafts in the chart: Soulreaving, Enforcing, Invoking, Evoking and Empty. The bar graph (admittedly, not the best chart type to describe population, but it'll suit this blogpost) will compare the two countries' populations for each type of ethercraft.

For this post, we'll focus on the X-Axis descriptors, the ethercrafts. Currently, it describes those by the following code in the Highcharts javascript in the ajax file:



Going down the script:

The first variable, ethercrafts is a list of the ethercrafts as strings in an array which will be the xAxis categories, (we'll talk about this further down). Next is an array to describe the countries that will be the series in the graph. Each country is listed, along with the population of people with a certain ethercraft described in magic constant numbers. We don't want magic numbers, but for the time being, those will work for this example - country population variables will come next time as I make progress on highcharts.

Next variable is the options that we'll pass into the chart we want to make. Highcharts lets you name this anything you want, as this variable will just contain a lot of data which will be passed in as an argument for the Chart function which expects its options. The options include where it's being rendered to (in this case, an HTML object with the ID 'container') and the type of chart, which is bar, the title of the chart, what the categories in the xAxis is (which is our ethercrafts variable, where it expects an array), and the yAxis, where we describe the numbers as population in thousands. Lastly, we describe the series - which expects an array, along with the relevant data. It passes in the countries variable from before.

Lastly, we have the last variable which is a function to create a new highcharts chart with our options passed in as the first argument.

We'll focus on the ethercraft variable here. Right now, this is what we have for ethercrafts in the AJAX file:


But these are all constants. What if (and we have) an Ethercraft class in our ActiveRecord, which also describes these 5 currently and would like to use that? Imagine if there's more than just 5 ethercrafts, like how there's more than 5 different genres of music and we wanted the graph to reflect that?

We'll first need to get all the ethercrafts in ActiveRecord first, and present it as an array of the names of Ethercrafts. Otherwise, we'll just have an ActiveRecord Relation object that describes all the items or the Object References to the Ethercraft items, or worse.

Firstly, in the controller where the graph will be displayed, we can use the following private method and store it in a single instance variable, such as @ethercrafts:



With that done, next we'll need to change the variable in our AJAX file to take in the collection of the different types of Ethercrafts from ActiveRecord (via our instance variable, @ethercrafts). To do that, we can go to our application.html.erb, and add in our header:


Then we should change the ethercrafts reference in the AJAX file and point it to window.ETHERCRAFT. And this should do it! Right?





...no? It doesn't work, because the syntax for performing ERB is expecting quotation marks around that. So we'll go do that:


And this will make:

...what on earth? Oh, because it expects an array, right? So adding a bracket surrounding the variable should close it up nicely:





This should do it:



 Not exactly what we expected. We got the names of the ethercrafts all there/ But they're covered in " before and after!

What exactly happened here? The long and the short of it is that during the processing via Ruby/ActiveRecord -> ERB -> Javascript -> HTML, the array of our ethercrafts were in this form:

["Soulreaving", "Enforcement", "Invoking", "Evoking", "Empty"]

However, through all that, the quotation marks were read and parsed into the " text. So how do we fix this? Let's take a look at the source code while we're at it (very important thing to do as well, it's a good habit I've picked up.).


Our window.ETHERCRAFT has our ethercraft array within the array we added earlier. That's strange! However, this does explain some things. When JavaScript expects an array of strings, like when we are trying to define the X-Axis Categories for Highcharts expects quoted strings separated by commas. Now, the quotes don't exist when Javascript reads it, so we end up with the " mess or a plain syntax error prior to adding our overarching quotes or array boxes. But now, we end up with this.

So how do we fix it? A handy function to use is to use the raw form of our HTML to be read into the Javascript, which we'll add to our ERB file as we render our ethercrafts variable:

We remove the quotations and the array, as our instance variable already contains our square array and our strings separated by quotes and covered with individual quotation marks for each through our method in the controller. This is exactly the format Javascript will expect, so this is what we get:





Hooray! We've done it.

And so ends this post where I describe my morning. I get closer to making highcharts usable for census data, and learn how to move raw data from Rails to ERB to JS to HTML. A very nifty lesson, overall.

Hope this helps. Comments, criticisms and advice are wholly welcome!


Thursday, 25 September 2014

Starting Highcharts

I was looking into highcharts due to the popularity of presenting data on websites and apps nowadays. Highcharts is part of a series of JavaScript based apps that features interactive display along with HighStock and HighMaps - and they look pretty sleek.

As you highlight your mouse over the bars, a small box describes exactly what you want. And the implementation thus far seems to be so simple. I'll be working on this over the next few days to see how I can put in variables as data - the site has a way for people to get started.

But, keep in mind that on Ruby on Rails we like to compartmentalize our scripts and sources. Normally, you'd put in your head tags  (as instructed in the Highcharts tutorial:)


<'script' src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></'script'>
<'script' src="http://code.highcharts.com/highcharts.js"> </'script'> 


But there is now a gem for highcharts, highcharts-rails. So all we'd need is to add this gem to our gemfile and we can just plug in highchart scripts and methods into our Ajax file:


In Gemfile:
gem "highcharts-rails", "~> 3.0.0"


In app/assets/javascripts/application.js, add to the end:
//= require highcharts
//= require highcharts/highcharts-more


And then we're all set. This above example was as easy as making a new div with the id 'container' anywhere on my HTML, and using the following, copy pasted code from the highcharts example into your JQuery code:



From the look of things, we could probably put in variables in the array. This is looking like straightforward JQuery. I will definitely be meddling around here to get what I want for statistics. It definitely seems like a versatile and very powerful chart API.

Wednesday, 24 September 2014

The little things between form and 'form'

After a long trip following my graduation from Metis, I went back proper into a routine this week. And today, I learned a great tidbit about how to render forms in Rails, very simple but it saves me a lot of time from now on.

I used to write the following:


<%= render 'form', form: form %>

For rendering a form partial. I couldn't just not put in the 'form: form' part because it would always say that form doesn't exist in the partial (in the form partial, there was - obviously, a form with it's associated fields designated as form such as form.text_area, and so on).

However, one of my colleagues pointed this out to me that I could just do:

<%= render form %>

The difference? By removing the quotations, Rails magic will immediately do the previous line I put up for me. That is very convenient, and actually solves a lot of my hassles (I've always wondered how people just write render form - and now I realize it's just the quotes!).
 

Sunday, 31 August 2014

HabitRPG

So I was wandering around Hacker News today, and I came across something exactly what I was hoping to do last year!

Enter HabitRPG, a to-do list with a gamified twist. It has dailies, to-dos, habits (good and bad) and the ability to reward yourself. Basically, you have an avatar, with stats and experience points - things you'd expect in an RPG - and as you do tasks, dailies or good habits, you gain exp and money. With money, you can buy new costumes or pets for your avatar - very addictive things that are used to be so common all over the internet (NeoPets, that dragon egg signature thing on forums?). It's genius, because people who are attracted to such a feature will find themselves much more motivated.

So how does one motivate oneself to do it further? Social networking, of course. It integrates with Facebook - which is something I have to check to be sure, but if it does what I think it does with Facebook, you'll be able to see each other's progress and that usual peer pressure does the rest. It's kind of like how you brag to others about what you're doing - you're much more likely to follow through after!

You can also form parties, too, and take on various quests/challenges. In parties, you can see each other's progress (another form of peer pressure), and challenges involve giving yourself new tasks between you and your party that you share and do.

It's great! I'm definitely going to use this between bouts of Trello (They have a Trello board too for things they need doing, to boot.)

On another note, they need people to contribute! People to spread word of mouth, people to write, people to art, and people to code! For code, they use Angular JS  for both web and mobile (apparently, it makes it very easy to transfer between web and mobile codes.). They use Mongoose for the database and ExpressJS for their API server. Some things to look into, I'm sure if I want to contribute. It's a worthwhile effort, I think, and Angular is pretty big lately.

In the meantime, though, I'm going to go gain a few levels as I complete tasks. :D