Now that we have successfully implemented a published_on field and methodology into our Article Model (see the part one article), it is time to implement the necessary code so that the functionality desired, published articles sorting by descending data of publication, actually works properly behind the scenes to make it show up properly for you, my readers.

Additionally, some minor layout/display housekeeping will also be undertaken at the same time, as the views (the pages you the user look at for the lay people among you) require attention anyway to fully complete the primary thrust of this action.

So, let’s get started, shall we?

Change the sorting

Now that I have successfully set up the idea of a publication date in the first article, I can actually use it for what I had intended it to be for, which was to display my articles in the descending order of their publication date so that the newest article is always the first one listed. (Having control of the sorting this way is important for a couple reason. Firstly, though it hasn’t happened yet, I might have multiple articles in progress and finished in an order other than their dates of creation and I want them ordered that way. Secondly, it’s always helpful to have some sort of your own sort when displaying a group of objects that come from the same Model as Rails may sort them in unexpected ways if you let it). As always, the way to go about this proper is to write your failing tests, write the code that passes the tests, refactor as necessary.

Now, at first, I thought this might fall under the concept of controller testing because I’m just testing the index method of my Articles Controller. After a series of mishaps and web searches, I found that maybe controller testing wasn’t for me in this instance. The method I’m testing is actually a conditional method that returns one set of articles for you all and a different set (that includes the unfinished ones) for the administrator (that’s me for now). Even with stubbing (see the model testing article for my first uses of this) out the if clause of the index method, I couldn’t figure our how to write the proper should or expect that would return my test articles in the right order. So, after a few hours of fruitless attempts I moved on to the idea to do this as a feature test.

I had already created non_admin_index_spec.rb as a way to test that this index method would display the proper set of articles be it the masses or a logged in admin viewing the index page. (I realize I should probably change the name of that file now, but I haven’t yet). Taking advantage of the lovely Date.current combined with the days_ago(x) helper (thank you The Rails Way 4), I quickly altered the existing spec to include a couple more FactoryGirl created articles with ‘earlier’ publication dates than my current test article and then turned my attention to writing the test.

After some hemming and hawing with myself, I realized that to write the tests, the way that I could make work fastest involved altering the index view so that the `` displaying the articles had an id (#articles) and that each article itself was within a div so that I could write RSpec code that would look in the ‘child’ divs of #articles in order and find that my test articles output in the way that I had wanted. As simple as that might sound to you, it took me a little bit to work out how to even write the tests properly.

I had used the concept of within previously when working through the Rails 4 In Action book (which I’m still in the middle of by the way) and had used it simply before, but it took me some trial error to figure out that i had to look not only within the #articles div, but while in said div I had to look within the child divs, which I figured out started at 1 (not zero like most programmers are used to when dealing with arrays and such, 1 was actually 1 here, not 2). So while i was in the #articles div, I had to look within("div:nth-child(x)") where x went 1, 2, 3, to determine that the proper title and published on date showed up, and that published on date led to another little complication.

You know when you read a blog and it tells you that an article was published 17 hours ago and then you go back a few days later and see the same article was published 2 days ago? Ok, maybe you do and maybe you don’t, but before I made it this far in my learning path, I used to think that was some pretty hard stuff to write, but since Rails tends to be awesome and commonly used stuff is often built into the soup, I could implement this easily. I just used another Date Helper method, that I’m sure almost everyone who uses Rails knows and loves time_ago_in_words. Of course, i wanted to test that this worked, so when I wrote my tests looking for the Article title in the right place, I double checked to make sure the publication date read properly. My presumption was that I just had to write an expect statement tested that the time_ago_in_words(publication date of article) was on the page, and that’s what I did. Sadly, my test exploded.

Exploded is what I call (as of now) when you run your tests and they don’t just ‘fail’, they thow a long list of Rails errors that means you’ve done something that broke RSpec’s ability to run. Fortunately, as always, Stack Overflow to the rescue. I learned through that wonderful site that the Date Helpers aren’t automatically included in your RSpec library of things you can use, but like the Warden tests added to help with devise, there was a pretty simple solution. Similar to the Warden solution (though simpler because you don’t have to reset anything at the end), a line of code was required in the rails_helper.rb file with in the RSpec.configure block so that my tests could access various helpers, like time_ago_in_words:

config.include ActionView::Helpers::DateHelper

(Side note, I’m writing this after the fact, so I’m not 100% sure, but I think FactoryGirl ran the days_ago helper without the include. The include was only required once i tried to test the content using the time_ago_in_words Date Helper. Perhaps I will investigate that in the future, but for now, it’s not all that important)

Ok, so now my tests were correct, but hey remember that’s only step one, the tests, they’re a written, and they’re a failing, which is awesome, but now we need to make them passing, so that meant writing all the code I needed so that my readers would see all the published articles on the front page reverse sorted by the date they were published. That sounds like it would take a lot of work right? Well, ok, if you’re reading this and don’t write any code ever at all it sounds like a lot of work, but once again Ruby makes it easy and quick to write RDBMS independent code that will correctly write the query I need be it in my development database (SQLite) or the Heroku production database (PostgreSQL).:

scope :published, -> { where(status: "published").order(published_on: :desc)}

Drop that line of code into the file where all the model stuff is for my articles (app/models/article.rb) and that should do it. Run the tests, all my new tests pass, but another test fails (this is why good testing is important folks). When the admin (me) logs in, he goes to the same index page as everyone else but all the articles show up, and draft articles don’t have a publication date, which of course causes a problem when I’m trying to display the date contained within published_on for each article. Draft articles return nil and Rails doesn’t like nil.

Well that’s ok though, this I know how to handle, I just wrap the publication date display in a quick with a corresponding at the end of the code block that displays the publication date, and we’re good to go on that fact. Test my file again, and we’re all green folks.

Now, something about this index page was bugging me. I mean not only did I not like how it looked, there was no comment count on this page. I thought there should be (at least for me so when I come to look I can see if there are any new comments, right, cause I don’t have any notification to let me know when a new comment is received, but I might build some later who knows), so I set about the process of doing just that, which as usual involves writing tests, failing, and then writing code to pass them. I won’t bore you with the details as I think we’ve established that the basic testing takes more time to explain than necessary and the principle of what was done is the same as above. However, I will discuss one point.

When deciding if I should do this, I had a thought that I would get a similar nil problem as I did above for an article that didn’t have any comments. I decided to run a quick simulation to see if that would be the problem. A quick jump into the rails console and I test out Article.second.comments.count (the only comments in the development database belong to the first article) and find that it returns zero, so I whouldn’t have to write any conditional display to get my tests to pass, and pass they did. Quicker this time than before, so perhaps I’m reinforcing and learning.

Then I go and do my standard GACP to both my Github repository and my Heroku Repository because I want these changes live right away.

General Housekeeping Changes

Well I’m at it, I decided to do some basic housecleaning that doesn’t really need a solo article or a lot of discussion as nothing significantly new was leared.

  1. When I log in as the admin I get a little Sign Out option on the right part of the navigation bar at the top. I wanted to add a link there so that I could create a new article by clicking it instead of typing in the address directly. Wrote test in proper existing test file, failed, included proper `