Internet Explorer Only Prints First Page

We recently had an issue on our site printing user resumes. Resumes that should have been multiple pages were only being printing the first page in Internship Explorer (and the bottom of the page even printing Page 1 of 1 – so clearly IE thought that there was only one page). The issue seemed to the be the fact that our print.css file was using absolute positioning on an element. Although Chrome and FireFox were able to print correctly regardless of this styling; IE was not.

@media print {
  .main-content {
    position: absolute; top: 0; left: 0;
  }
}

Removing the absolute positioning caused IE to recognize the other pages. Of course we had to readjust our css so that the printing styles still looked how we wanted. Hopefully this helps you solve any similar issues you maybe be having.

Amazon AWS EC2 Instance Not Unresponsive (No Support)

If you are using Amazon AWS for cloud hosting without support added to your account, then every once in a while you will have to deal with an instance that has become unresponsive (can’t connect to it and it won’t respond to reboot, stop or force stop). If you don’t have support you are essentially stuck to posting on their forum’s asking Amazon to reboot your instance for you. Here is a link to a forum post I made in April 2013 you can use as a sample if you ever run into this issue:

https://forums.aws.amazon.com/message.jspa?messageID=440609

Hope this helps you out!

Logrotate on Windows for Managing IIS Logs

I was recently trying to find a good solution for deleting old IIS logs files for our windows servers. I searched the web for anything equivalent to logrotate on linux for a Windows machine but had no luck (actually there was IISLogs, which was something you had to pay for). After much searching I stumbled across this Stackoverflow post which gave the simplest solution to the problem I was facing (we just needed to delete old log files).

forfiles /p "C:\inetpub\logs\LogFiles" /s /m *.* /c "cmd /c Del @path" /d -7

This answer was posted by Reditus Solutions, LLC.

One issue I faced when creating a scheduled task with this command was the command would bring up prompts which would never receive a response and the task would just hang. You can add the /p flag (which silences all prompts) to the Del command: “cmd /c Del @path /p”

Unit & Integration Testing Solr w/ RSpec, sunspot_solr, sunspot_test & sunspot_matchers

The sunspot_test gem allows you to add a tag to a describe/context block automatically starting and stopping a Solr instance within that context.

describe "searching", search: true do
# some code
end

The sunspot_matchers gem provide custom RSpec matchers that you can use to verify that the search you are running using sunspot is correct.

The goal of these matchers are to make it easier to unit test search logic without having to construct the individual fixture scenarios inside of Solr and then actually perform the search against Solr

The gem essentially decorates the Sunspot.session to intercept calls made to it. In order to use it you will have to add the following to your spec_helper.rb file:

config.before do
  Sunspot.session = SunspotMatchers::SunspotSessionSpy.new(Sunspot.session)
end

This is perfect for unit tests since they will not need an actual Solr instance to work and therefore will be much faster. You use the custom RSpec matchers such as be_a_search_for or have_search_params to verify that the Solr query your code will execute is correct. Then, in your integration tests you can actually do an end to end test with an instance of Solr.

This is exactly what I set out to do, however the config.before block in the spec_helper.rb file intercepted the Sunspot.session and always returned an empty array (even in integration tests). Since I was using the sunspot_test gem which requires adding a tag (search: true) to your describe block I used the following approach to tell RSpec that for these tagged blocks use the actual Solr.session.

config.before do
  Sunspot.session = SunspotMatchers::SunspotSessionSpy.new(Sunspot.session)
end

# SunspotMatchers will keep a reference to the original session so we can access it like so
config.before(:each, search: true) do
  Sunspot.session = Sunspot.session.original_session
end

In this way, anytime we tag a block with search: true we will be using the actual Solr session. Hope this helps someone :-).

Free Heroku WebSolr Staging Environment

We were using WebSolr for our Rails application on Heroku. We decided to add a staging environment that mimicked our production one so that we could verify and approve changes in staging prior to deploying to production. We needed to have the WebSolr add-on, but the only problem was that there is no free version to use in our staging environment. We don’t want to pay $20/month to add WebSolr on Heroku for staging! So I searched Google and the only solution that seemed to come up and be free was hosting on amazon ec2. So we went ahead and proceeded with this, but in the meantime I emailed the WebSolr guys asking if we could get free service for staging. DON’T USE EC2 because you can actually get WebSolr for free. Here’s how:

This is a response to one of the emails I sent to WebSolr and it identifies how you can use WebSolr on Heroku for both production and staging:

It turns out that customers who add Websolr via Heroku actually get two indexes with the plan. It’s not really called out on Heroku’s site, but it was designed that way for exactly the use case you’re describing. If you’re currently only using one of those indexes for production, you can go ahead and create the second “staging” index at no cost.

There you have it. Just add another index on your production WebSolr account and connect your staging account to it. This is why they created the ability to have two indexes.

Hope this helps someone.

Looksy – Updates On My ActiveRecord Caching Gem

I just updated Looksy, https://github.com/aboghosian/looksy, a gem I developed to add a caching layer between your ActiveRecord models that represents look up tables in your database. Originally the gem added the following methods:

  1. #fetch_all – retrieves all records from cache
  2. #fetch_by_id(id) – retrieves record by id
  3. #fetch_by_attribute(‘value’) – retrieves first record matching attribute (can supply multiple attributes by separating with _and_; #fetch_by_this_and_that(‘this’, ‘that’))
  4. #fetch_all_by_attribute(‘value’) – retrieves all matching records (can supply multiple attributes as above

A few new methods have been added and here they are:

  1. #fetch_first – retrieves the first record
  2. #fetch_last – retrieves the last record
  3. #fetch_last_by_attributes(‘value’) – retrieves the last matching record (the opposite of using #fetch_by_attribute and supports multiple attributes separated by _and_

To use the gem simple include the Looksy::Cacheable module in your ActiveRecord class (or any class that responds to .all).

class JobType < ActiveRecord::Base
  include Looksy::Cacheable
end

And just like that these methods are added to your class. By default the gem will attempt to use the caching store of Rails.cache if you are using Rails and if not it will default to Looksy::NullCache which essentially does not caching (lol). You can substitute your own cache and set other options the following way:

class JobType < ActiveRecord::Base
  include Looksy::Cacheable

  self.cache_store = MyCacheStore.new
  self.cache_key = 'MyKey'
  self.cache_options = { expires_in: 30.minutes }
end

The gem was a by product of some coding I did at work to cache our look up tables so we didn’t have to hit the database each time to get the data (which changed infrequently). Hope you enjoy and I appreciate feedback (this is my very first gem I’ve published).

Looksy – My Ruby Gem on Github

I published my very first gem on RubyGems today and the source code is located on GitHub at https://github.com/aboghosian/looksy. Check it out when you get the chance. The gem is the result of a project we were working on in which we wanted a centralized way to cache our look up tables so we didn’t have to hit the database each time to retrieve them (mainly because they changed very infrequently).

Looksy allows you to place a caching layer between your look up tables and ActiveRecord classes. Here is how it works:

class PaymentType < ActiveRecord::Base
  include Looksy::Cacheable
end

# retrieves all records from cache or populates cache from db
PaymentType.fetch_all

# retrieves record matching id
PaymentType.fetch_by_id(id) 

You also get dynamic methods just like ActiveRecords dynamic finders, except instead of using find to prefix your method calls you use fetch.

class PaymentType < ActiveRecord::Base
  include Looksy::Cacheable

  # attributes include :name and :status
end

# retrieve record by name
PaymentType.fetch_by_name("CreditCard")

# retrieve all records by status
PaymentType.fetch_all_by_status("active")

You can chain multiple attributes together as well.

class Coupon < ActiveRecord::Base
  include Looksy::Cacheable

  # attributes include code, status and association_type
end

# retrieve record by code and status
Coupon.fetch_by_code_and_status('100PERCENTOFF', 'active')

# retrieve all records by status and association type
Coupon.fetch_all_by_status_and_association_type('inactive', 'whitelist')

Flattening Array Containing Hashes in Ruby

We ran into an issue in one of our tests in which we needed to take data that was returned in the format of an array of hashes (which could contain nested arrays of hashes), and convert it into a flat hash (no nesting). Here’s a example for us visual people:

[
  { title: 'title' },
  { name: 'name' },
  details: [
    { item1: '1' },
    { item2: '2' }
  ]
]

This needed to be converted to this:

{
  title: 'title',
  name: 'name',
  item1: '1',
  item2: '2'
}

We didn’t have to worry about overlapping keys because we knew beforehand that there would never be duplicate keys in our original data. Here’s the solution I came up with.

def array_to_hash(array)
  array.inject({}) do |memo, hash|
    hash.each do |k,v|
      if v.is_a?(Array)
        memo.merge!(array_to_hash(v))
      else
        memo[k] = v
      end
    end

    memo
  end
end

This handles any level of nesting that you may have. I personally thought it was a simple solution :-).

Abstracting Away Gem Dependencies In Rails

As I have been working with Rails for the past few years there is one thing that has constantly bothered me on most projects I work on. The problem is the hard dependencies that Rails applications have on gems. Generally, when I have wanted to connect my application with Twitter I would:

  1. Go to GitHub and find a Gem
  2. Add it to my Gemfile and run bundle
  3. Start referencing the gem directly in my code

Number 3 is where the problem lies. If I am calling this gem directly, then I have a hard dependency upon it. If there are breaking changes in future releases (e.g. api changes) or if we want to use a different gem then we have to find all the places where we referenced this gem and make the necessary changes. In .NET (C#) you can easily abstract away dependencies by creating an interface and relying upon that interface in your calling code rather than a concrete class. In this way, your calling code is unaware of what your implementation is, all it knows is that as long as the class implements the interface it can call certain methods and properties on an object. But how can we deal with this problem in Ruby?

I think that the simplest way is to wrap gems in our own libraries or classes. Say for instance, that we have a Rails application called MyRailsApp and we want to use TwitterGemX in our project. Rather than reference TwitterGemX directly we can create our own wrapper class that will implement the interface we need for our project.

class MyRailsApp::TwitterClient
  def initialize(config = {})
    @inner_client = TwitterGemX.new(config)
  end

  def tweet(message)
    @inner_client.update(message)
  end
end

In this way any custom functionality you might need to add (e.g. logging) can be done in your own class rather than monkey-patching or forking a particular gem. I find this a better route to go than to reference gems directly. Not only this, but your calling code is completely unaware of what specific gem you are using. If Twitter updates their api and you find that the gem you are using is no longer compliant with that api, there is only one place that you need to go to make changes. If you want to switch to a different gem, you can do that as well. All your calling code knows is about MyRailsApp::TwitterClient :-).

Facebook Share And/Or Twitter Share Url Parameter Doesn’t Work

If you are trying to test out Twitter and/or Facebook sharing on your local development environment there is one thing you should be aware of. If you are passing a url parameter and that url parameter contains the “localhost” as your host then Facebook and Twitter will ignore these parameters. I experienced this recently while working on a Rails app.

Twitter

https://www.twitter.com/share

I would pass both tweet text and url parameter but only the tweet text would show up. This was caused by having localhost as my host. So in your staging or production environment these will work fine. If you want to just quickly verify then either in your tests or in your app add a :host option to your url helper and you can see that it works fine.

Facebook

https://www.facebook.com/sharer/share.php

I don’t know if this endpoint is officially deprecated or not but you can use Facebook Dialog instead.

With Facebook I would pass title, url, description but nothing would show up. Again this had to do with the fact that the url was using localhost as its host. Once I added a :host option to the url helper it worked fine. Just remember to remove the host option once you verify that your link to Facebook actually works properly.