Truncating URLs w/PermalinkFu
I use PermalinkFu for generating nice slugs for URLs here, at Artlog and in the Backlight CMS that runs a number of websites for friends like Marlene Marino and A Crime So Monstrous.
In any case, it’s a great plugin, but it’s begun to bother me that it can generate some massively long permalinks if left unchecked. So for the new Artlog site I am going to truncate the permalinks into some limited number of words.
For example, I’ve set the note model to generate the permalinks (saved in a “permalink” column in the DB) this way:
class Note < ActiveRecord::Base
def to_param
"#{id}-#{permalink}"
end
before_save :create_or_modify_permalink
def create_or_modify_permalink
self.permalink = PermalinkFu.escape(("#{name}").to_s)
end
end
That’s fine in most situations, but if the note’s name is long you run into issues.
>> n = Note.new => #<Note id: nil, name: nil, permalink: nil, created_at: nil, updated_at: nil> >> n.name = "I just flew back from Chicago and boy are my arms tired" => "I just flew back from Chicago and boy are my arms tired" >> n.save! => true >> n.permalink = "I-just-flew-back-from-Chicago-and-boy-are-my-arms-tired"
That’s awkward – particularly if you are RESTing it up and your edit URL ends up looking like
/notes/1-I-just-flew-back-from-Chicago-and-boy-are-my-arms-tired/edit
So I am going to go ahead and create an evil twin plugin to generate more sane slugs and have the new method available across all models (rather than having the fix only available in the note model).
In vendor/plugins create a directory called “permalink_fu_hacks” or something and create an init.rb file in that directory (/vendor/plugins/permalink_fu_hacks/init.rb) that looks like the following:
PermalinkFu.module_eval do
class << self
# truncate the permalinks to x number of words (specified in length below)
def truncated_escape(str)
length = 6
PermalinkFu.escape(("#{str.split()[0..(length-1)].join(' ')}").to_s)
end
end
end
You can change the length we specify to whatever you’d like. Six may seem like to many or too few words to you, but it doesn’t really matter; you’re largely just setting an upper limit to prevent URLs from getting way too long.
You can now change your create_or_modify_permalink callback in the note model to this
def create_or_modify_permalink
self.permalink = PermalinkFu.truncated_escape(("#{name}").to_s)
end
and you’ll end up with a better permalink:
>> n.save! => true >> n.permalink = "I-just-flew-back-from-Chicago"
→ The Rubyist
A technical magazine focused on technical content and the happenings in the world of Ruby, Rails, Merb, and anything else related to our favorite programming language.
Searching multiple models w/ Thinking Sphinx
Thinking Sphinx is a really sweet Ruby library that hooks ActiveRecord to Sphinx and hooks up to will_paginate out of the box.
Sphinx is a very fast search engine that indexes data and provides flexible ways of searching it. Thinking Sphinx allows you to link up your models into Sphinx simply and painlessly – because let’s face it, searching across multiple fields using SQL is a pain in the neck.
TS is easy to implement and reliable (haven’t seen any corrputed indexes yet) – we are using it on the new Artlog (and in combination w/ Geokit geographic for geographic + text searches).
Ryan Bates posted a good intro tutorial this morning over at railscasts.
Here’s a quick tip for folks looking to search across multiple models at once.
You’d traditionally build your actions this way (search_controller.rb):
def notes @notes = Note.search params[:search], :per_page => 10, :page => params[:page] end def users @users = User.search params[:search], :per_page => 10, :page => params[:page] end
But to search across multiple models, you can interact with ThinkingSearch::Search directly and set the action up thusly:
def index @results = ThinkingSphinx::Search.search params[:search], :per_page => 10, :page => params[:page] end
And the view could look something like this:
<%- @results.each do |result| -%>
<% if result.class == Note %>
<%= render :partial => 'notes/note', :locals => {:note => result } %>
<% elsif result.class == User %>
<%= render :partial => 'users/user', :locals => {:user => user } %>
<% end %>
<%- end -%>
<%= will_paginate @results %>
I am rendering the user and note results in partials – you don’t have to do it precisely this way, of course. It’s just to get you started.
→ nycruby
Who we are
We’re a group of Ruby and Rails programmers who live and work in the New York City area. Developers and dilettantes of all skill levels are welcome.Meeting Place and Time
We meet on the second and fourth Tuesdays of the month. The first meeting centers on presentations by one or more group members, and the second meeting is an unstructured hackfest (bring your laptop).
I’m finally going to make it to the local rails meetup tomorrow night.
Introducing Backlight
Nearly every web project I Am Still Alive has produced for clients in the last year has required some content management system. In all of those cases, I’ve provided a Rails-built custom-designed backend app to manage the various sites.
Over the last few months, I have organized the diverse functions (blog, photo gallery, tagging, drag-drop sorting, user authentication, contact management, geolocation, e-commerce, event management, ...) into one stable, flexible system that I can redeploy fairly effortlessly. It’s been working out well and clients have really taken to the system.
I have taken to calling the app ‘Backlight’ as it largely started coming together while working on sites for a pair of photographers (launching shortly).
In any case, it’s my plan to repurpose and then release Backlight as a hosted service (websites with custom domains hosted/powered by one app) in the next few weeks. I am going to post updates every now and again about the process of refining it further in the run up to launch. The app is actually quite similar to the hosted artist portfolio management system we have in the works over at Artlog.
has_many :through with has_many_polymorphs
So, I have been using Evan Weaver’s awesome has_many_polymorphs rails plugin for a while now. It has saved me a lot of frustration, for sure. Evan is also working up a tagging generator for has_many_polymorphs which should help solidify has_many_polymorphs position as the replacement for acts_as_taggable (which is basically deprecated at this point, I think). The plugin is actually much more than just a tagging engine tho. You can have a look at the plugin’s own page for a full (and current) run down of what has_many_polymorphs can do.
For a couple recent projects, I have used has_many_polymorphs to set up has_many :through relationships and it’s actually been such a boon that I reckon it may benefit other folks for me to commit the process to writing.



