Categories
blog Code meaningful labor rails ruby

Add automatic URL generation to your Rails App (+ a little about ActiveAdmin)

It’s easy to add a “url” or “slug” field to your rails app, and override the to_param function to report that field. A route can then look for an alphanumeric parameter, like this:

match "pages/:slug" => "purchases#show_by_slug"

But how to generate them without too much manual labour? [manual labour is a good thing, relying on well written gems is sometimes better]

Categories
blog Code effective social media ruby

Getting instagram images with OpenGraph

I previously mentioned how simple it would be for Twitter to use OpenGraph to grab images off Instagram to restore the user experience removed when Instagram stopped posting image meta data to twitter.

Categories
blog Code

Instagram removing full Twitter integration shouldn’t be a big deal

Last week Instagram stopped posting direct image information to Twitter when you shared an image. It means that instead of seeing a picture inline with your tweets you need to click the Instagram link to load the image in a browser window. Most other image services use Twitter’s “media” tag to allow the image to be shown inline.

Instagram, now owned by Facebook, have clearly got a reason for doing this: whether it’s to do with tracking user activity more closely, a future addition of advertising on the Instagram pages, or to more closely integrate the Instagram web pages with Facebook.

Categories
Code heroku ruby

Find the total number of rows in your Rails app.

Heroku have just introduced a limit on their free database of 10,000 rows. As their robots convert each of their Rails 3 apps to a new database architecture, any database approaching 10,000 rows will send out an email warning the user.

Categories
blog Code giants heroku rails

Reducing Heroku Cost with Asset Pipeline Sync

GiantsLive which is hosted on the new heroku Rails 3/Cedar platform a single ‘dyno’. If you don’t know what heroku is, essentially it’s a cloud web hosting platform, and one of it’s finest features is that your first 750 ‘computation hours’ in a month are absolutely free. Properly free, like a lunch at that church on Stranmillis Road on a Thursday.

Categories
Code learning rails ruby

ActiveAdmin on Heroku (Rails 3.1)

I wrote a post detailing some issues I had with ActiveAdmin and Heroku with Rails 3.1.

It’s probably entirely out of date, but in case its of any use for you, it’s still archived here.

Categories
Code ruby

Blog Move 1: Getting WordPress data to Ruby using XML

Step 1 in the “Moving my blog” process is “Extract the current site’s data into a manageable format”

Frankly, that’s easy! WordPress has a functionality to export the site’s content to a single XML file containing all the published Categories, Tags, Posts, Pages and Comments. To do this (WordPress v2.9.2) click Tools > Export and save the file. In previous versions of the software I believe it’s under the Manage menu.


I’m aware I could import the data directly from the WordPress database (to wherever it goes in the end) but let’s imagine we can’t. Anyway, database access would be tediously slow and inefficient to test against and implement.

A quick google for “import wordpress xml ruby” threw up nothing helpful so I turned to the Ruby XML libraries. John Nunemaker “feverishly posts everything he learns” at railstips.org and has two articles of use here:

The latter deals with three different ruby xml libraries and compares their speed, ease of use and how nice their names are to say. He puts REXML, hpricot and libxml-ruby. I’ll save you the pleasure of reading the article (if you like) and ccv John’s summary:

“Libxml is blisteringly fast, [but] Hpricot has cooler name, REXML and Hpricot both feel easier to use out of the box”

And there you go. Hpricot it is!

Now to get the data into Ruby. After a quick glance at the rubytips article and The RDocs I put together this code as a starting point:


cats_hierarchy={}
(doc/"wp:category").each do |category|
    cat_name = category.at("wp:category_nicename").innerHTML
    cat_parent = category.at("wp:category_parent").innerHTML

    if cats_hierarchy.include? cat_parent
        cats_hierarchy[cat_parent] = cat_name
    else
        cats_hierarchy[cat_name] = []
    end
end

cats = cats_hierarchy.to_a.flatten

That gives me two each to use Ruby objects each containing all of my category data: a hash which preserves the hierarchy of the structure and all the names in a linear array.


?> cats = cats_hierarchy.to_a.flatten.uniq
=> ["route66", nil, "rails", "american-2008", "reciprocal-affection", "hope-for-the-future", "code", "blog", "review-blog", "rant", "brands", "projects", "yab_shop", "textpattern", "meaningful-labor", "giants", "accessibility", "root", "charity-project", "apple", "xhtml", "america-2006-route-66", "ruby", "learning", "america-2007", "uncategorized", "iphone", "america-2008"]

?> cats_hierarchy
=> {"route66"=>nil, "rails"=>nil, "american-2008"=>nil, "reciprocal-affection"=>nil, "hope-for-the-future"=>nil, "code"=>nil, "blog"=>"review-blog", "rant"=>nil, "brands"=>nil, "projects"=>nil, "yab_shop"=>nil, "textpattern"=>nil, "meaningful-labor"=>nil, "giants"=>nil, "accessibility"=>nil, "root"=>nil, "charity-project"=>nil, "apple"=>nil, "xhtml"=>nil, "america-2006-route-66"=>nil, "ruby"=>nil, "learning"=>nil, "america-2007"=>nil, "uncategorized"=>nil, "iphone"=>nil, "america-2008"=>nil}

And so we have the starting point to getting this WordPress exported XML data into a Ruby application.

More soon.

Categories
blog Code learning rails

Ruby on Rails: Get some random records

EDIT AGAIN: Much better..

To get a ‘num_reqd’ array of random objects, you can use something like this.

  named_scope :large, :conditions => ['image_file_name IS NOT ?', nil]
  named_scope :small, :conditions => ['small_image_file_name IS NOT ?', nil] 

  def self.get(num_reqd,features_arr=[],size="large")
    if size=="small"
      collection = Feature.small
    elsif size=="large"
      collection = Feature.large
    end
    
    return collection if collection.size <= num_reqd

    # num_reqd.times{feature=self.random(collection); features_arr.push(feature) unless features_arr.include?(feature)}
    features_arr = collection.find(:all, :limit => num_reqd, :order => 'rand()')

    if features_arr.size < num_reqd
      return Feature.get(num_reqd, features_arr, size)
    else
      return features_arr
    end
  end

EDIT: It's much cleaner and easier to use something in the form below, though the following is probably useful in some cases and is possibly interesting as a code snippet.

User.find(:all, :order => 'rand()')


---- end edit.

Working from a baseline of the code found here at almosteffortless.com I've extended a 'random record grabber' to get a specific number of unique records from a Rails data table.

Basically - the random method makes a database call to get the ids of a table, and sends back a random entry. self.get is a recursive method which provides a 'total number required' and a base array to start from (if you wish to specify entries to appear in the otherwise 'random' list). First year computer science should help get your head around the rest!

def self.random
    ids = connection.select_all("SELECT id FROM features")
    find(ids[rand(ids.length)]["id"].to_i) unless ids.blank?
  end

  def self.get(num_reqd,features_arr=[])
    num_reqd.times{feature=self.random; features_arr.push(feature) unless features_arr.include?(feature)}

    if features_arr.size < num_reqd
      return Feature.get(num_reqd, features_arr)
    else
      return features_arr
    end
  end

Be aware, there is more efficiency to be found in the database call (i.e. it should be cached). Also, you'll want to be sure there are at least 'num_reqd' items in the database.

Categories
Code

Harry Ferguson Memorial CMS choice – Textpattern

The last few days I’ve been putting the finishing touches to the CMS behind Harry Ferguson Memorial.com. Initially completely in hand-coded HTML (to get it looking right without distracting myself hacking around in a CMS template styling system), it was time to choose a CMS to allow a certain amount of user updating to be done on the site.

I first experienced the Textpattern CMS through my participation in the TextDrive Joyent Mixed Grill “Venture Capitalist” life-time subscription. I was initially baffled by it’s usage of ‘forms’ ‘pages’ and ‘sections’ to categorise different design and structural hierarchy. Mostly using WordPress over the last few years on various sites and most recently developing a custom Rails CMS for the upcoming Bible Society of Northern Ireland website (note: current site is *not* of my creation) (launching in the next few weeks) I decided I needed to hunt around a bit. A quick play with Drupal left me unimpressed, I wasn’t going to touch Joomla (is it just me or does every site that uses it scream “look, it’s a site built using Joomla!”) and so I thought I’d take Textpattern out for another try.

Impressed by the fact it’s finally had an update (version 4.2.0 was released just a week ago (28th August) — after, I believe, a long hiatus — time to give it a spin once more.

Installation is pretty simple, quite lightweight; doesn’t require much in the way of configuration if you have a bog standard *AMP setup, just create or associate the database you wish to use (you can use a ‘_txp’ style suffix to append onto your existing DB) and create the .htaccess requested – it’s all explained on the linked instruction page.

I’m not going to do any sort of tutorial on the installation process, that’s been covered so many times, by so many people, I’d only do it a disservice. However, I have been using the YAB_Shop plugin, which is seriously lacking in documentation, with a 27 page forum post over at Textpattern.org. I’ll be putting together a few thoughts and instructions (which I found difficult to find) on the e-commerce plugin in the next few days and hopefully that’ll help someone out (and help me process and learn further!).

—-

Edit: I realise I didn’t really ‘review’ the experience, which I intend to do more so when I write about the plugin, most of my gripes are with the plugin workflow!