SMS Fu - Quickly & Easily Send Text Messages

Posted by on March 30th, 2008.

Having had to develop apps that relied on the ability to send text messages to members, I thought that it would be a good idea to turn some of that functionality into a plugin that would be easy to use. SMS Fu gives you the ability to be able to send text messages from your Rails app in less than five minutes. There’s no third-party gateway needed, as the phone number is converted into an e-mail address, which makes it deliverable to any phone.

Installation

git clone git://github.com/brendanlim/sms-fu.git vendor/plugins/sms_fu

Usage

Supported Carriers: Alltel, Ameritech, AT&T, BellSouth Mobility, BlueSkyFrog, Boost Mobile, Cellular South, Fido, Metro PCS, PSC Wireless, Qwest, Southern Link, Sprint, Suncom, T-Mobile (US/UK/Germany), Virgin Mobile, Verizon Wireless, Vodafone (UK,Italy,Japan)

To use SMS Fu, all you have to do is include SMS Fu in one of your controllers.

class ExampleController < ApplicationController
  include SMSFu
end

After this, go to /config/sms_fu.yml to change the default reply-to address with your own.

Phone numbers must not include any non-numeric characters, with the exception of ’+’ for International numbers. The three required parameters are the phone number, carrier, and the message itself. To find out just what you need to pass for the carrier, check the yaml file. The one line below will deliver a nice ‘Hello World!’ straight to your phone.

deliver_sms("5555555555","AT&T","Hello World!")

Since most non smart-phones only support up to 128 characters, you’re allowed to specify a limit to truncate the message delivered.

deliver_sms("5555555555","AT&T","Really long message ...", :limit => 128)

If you feel like rolling your own mailer, and not using SMS Fu to handle this, you can retrieve the the converted e-mail address for the phone number and carrier supplied.

get_sms_address("5555555555","AT&T")

That’s all there is to it! If you want to add your own carriers, just edit sms_fu.yml.

Share:

Comment on this post (0 comments)


Acts as Readable - Drop-in 'mark as read' functionality

Posted by on February 29th, 2008.

When writing an application there’s a number of times where it can be very useful to know whether or not a user has seen or accessed a piece of information. I recently had to write a solution to such a need and have wrapped up the result in a plugin for your enjoyment.

ActsAsReadable allows you to create a generic relationship of items which can be marked as ‘read’ by users. This is useful for forums or any other kind of situation where you might need to know whether or not a user has seen a particular model.

Installation

To install the plugin just install from the GitHub repository:

git clone git://github.com/mbleigh/acts-as-readable.git vendor/plugins/acts_as_readable

You will need the readings table to use this plugin. A generator has been included, simply type

script/generate acts_as_readable_migration

to get the standard migration created for you.

Example

class Post < ActiveRecord::Base
  acts_as_readable
end
bob = User.find_by_name("bob")

bob.readings                      # => []

Post.find_unread_by(bob)          # => [<Post 1>,<Post 2>,<Post 3>...]
Post.find_read_by(bob)            # => []

Post.find(1).read_by?(bob)        # => false
Post.find(1).read_by!(bob)        # => <Reading 1>
Post.find(1).read_by?(bob)        # => true
Post.find(1).users_who_read       # => [<User bob>]

Post.find_unread_by(bob)          # => [<Post 2>,<Post 3>...]
Post.find_read_by(bob)            # => [<Post 1>]

bob.readings                      # => [<Reading 1>]

And that’s all there is to it! It’s not an incredibly complex set of features, but I find it to be a pretty useful one. If you have any questions or issues, please feel free to post them on the public Trac

Share:

Comment on this post (0 comments)


acts_as_community private beta

Posted by on February 28th, 2008.

Today Intridea launched the private beta of acts_as_community, a community site for Ruby and Rails developers.

acts_as_community is a place for Rubyists and Rails developers to gather and interact. Our hope is to bring the community closer together in collaboration and communication so that everyone can benefit from others' experiences.

If you would like to join email us at aac@intridea.com for the beta key.

Share:

Comment on this post (0 comments)


Codebite: Generic "New Today" for Rails Records

Often times in an application you might want to know how many of a given model were created today. Rather than writing a custom method for each model, let’s keep it DRY and extend ActiveRecord:

class ActiveRecord::Base
  def self.new_today
    if self.new.respond_to?(:created_at)
      self.count(:all, :conditions => "created_at > (NOW() - 60*60*24)")
    else
      nil
    end
  end
end

This will return the number of records created in the last 24 hours by calling the model with new_today (e.x. User.new_today). It will return nil if the model does not respond to the created_at Rails timestamp attribute.

Share:

Comment on this post (0 comments)


ActiveRecord::Base.create_or_update on Steroids

I’ve been working a lot with seed data in my applications lately, and it’s obviously a problem that can be pretty aggravating to deal with. I ultimately liked the db-populate approach the best with the addition of the ActiveRecord::Base.create_or_update method. My one problem with it is that it’s based entirely on fixed ids for the fixtures, which is a pain to deal with when loading up your attributes from arrays. Here’s an example of what I was doing:

i = 1

{ "admin"     => ["Administrator", 1000], 
  "member"    => ["Member", 1], 
  "moderator" => ["Moderator", 100],
  "disabled"  => ["Disabled User", -1] }.each_pair do |key, val|
  Role.create_or_update(:id => i, :key => key, :name => val[0], :value => val[1])
  i += 1
end

I really don’t like having to put the i in there to increment up. Not only is it messier code, but it would be dangerous if I wanted to move around the roles. I also don’t want to have to have an id explicitly in each entry since I really don’t care what the id is. So I thought I would hack up a better solution for this create_or_update scenario and this is what I came up with:

class << ActiveRecord::Base
  def create_or_update(options = {})
    self.create_or_update_by(:id, options)
  end

  def create_or_update_by(field, options = {})
    find_value = options.delete(field)
    record = find(:first, :conditions => {field => find_value}) || self.new
    record.send field.to_s + "=", find_value
    record.attributes = options
    record.save!
    record
  end

  def method_missing_with_create_or_update(method_name, *args)
    if match = method_name.to_s.match(/create_or_update_by_([a-z0-9_]+)/)
      field = match[1].to_sym
      create_or_update_by(field,*args)
    else
      method_missing_without_create_or_update(method_name, *args)
    end
  end

  alias_method_chain :method_missing, :create_or_update
end

Basically, this allows me to call create_or_update with an arbitrary attribute as my “finder” by calling Model.create_or_update_by(:field, ...). To give it a little taste of syntactic sugar, I threw in a method missing to allow you to name a field in the method call itself. So now the code I wrote before can become this:

{ "admin"     => ["Administrator", 1000], 
  "member"    => ["Member", 1], 
  "moderator" => ["Moderator", 100],
  "disabled"  => ["Disabled User", -1] }.each_pair do |key, val|
  Role.create_or_update_by_key(:key => key, :name => val[0], :value => val[1])
end

This is much cleaner and prettier to look at, and also makes sure that it is keying off of the value that I really care about. This new create_or_update combined with db-populate creates the most powerful seed data solution I’ve yet come across.

Share:

Comment on this post (0 comments)


Using your dear friend, Enumerable

Posted by on January 28th, 2008.

I recently had to look over some code that was returning inconsistent results. I was able to fix the code with a few minor changes, but it was still very hard to follow. Take a look:


Continue reading this post

Share:

Comment on this post (1 comment)


Needy Controllers - DRYing Stylesheets, Scripts, and Fetching

Posted by on January 11th, 2008.

After developing a number of applications, there were some actions I found myself performing over and over again with each new controller in each new application. With my DRY-sense tingling, I decided to do something about it and create a plugin to clean up some of those repetitive tasks that were vital but annoying to set up. Introducing Needy Controllers.

Needy Controllers takes care of your controllers’...well, needs. You can include stylesheets, javascripts, and memoized record helpers in your controllers and views with a single command, and even use filter-chain-esque options to specify and tailor to your needs. Basically, it simplifies the process of:

  1. Including stylesheets in your app on a per-controller/action basis
  2. Including javascripts on a per-controller/action basis
  3. Having helper functions to fetch records in common RESTful resource mappings

Installation

git clone git://github.com/mbleigh/needy-controllers.git vendor/plugins/needy_controllers

Usage

Styles and Scripts

To use Needy Controllers for styles and scripts, you simply call a “needs” option inside your controller like so:

class MyController < ApplicationController
  needs :styles => :standard
  needs :styles => :show, :only => :show
  needs :scripts => :behave, :except => :show

  def index
    # this action will have access to the 'standard.css' stylesheet
  end

  def show
    # this action will have access to the 'show.css' stylesheet
    # in addition to 'standard.css'
    # but will not have access to 'behave.js'
  end
end

Now that you have created your behavior and style chains, you need to include them in the view. Luckily, this is exceedingly easy! Just include :needs in your include and link tags like so:

<%= stylesheet_link_tag 'something', :needs %>
<%= javascript_include_tag 'prototype', :needs, 'effects' %>

An additional benefit of the style and behavior chains is inheritance: namely, any controller that inherits from a controller with a stylesheet or javascript included using the above method will automatically have the same stylesheet and javascript included in itself. This allows you to easily set up includes that are scoped to your exact needs with as little work as possible.

Model Fetching

To use Needy Controllers for fetching records, you use it similarly, and it creates a helper:

class MyController < ApplicationController
  # here's a standard problem
  needs :record => :user, :from => :id, :as => :user
end

The :from and :as options in this example are the defaults (:id for :from and :as defaults to the name of the record). This will create a method (“user” in the example) that will be accessible both from the controller and from the view as a helper. It will find the record with a matching ID to the URL parameter associated with the :from option. Therefore if you had nested resources you could call it as such:

needs :record => :user, :from => :user_id

That’s pretty much it, just a few simple ways to make your coding life easier. As always, there is a Trac available for any issues and I would love to hear any feedback you might have.

Share:

Comment on this post (0 comments)


Beboist - A Rails Plugin for the Bebo Social API

Posted by on January 10th, 2008.

The Beboist plugin provides a Rails interface to the Bebo Social Networking API.

The plugin was designed from the ground-up to be flexible enough to accommodate any changes to the API, while at the same time providing a clean interface that will be familiar to most Rails developers.

Setup

  1. Ensure that the json gem is installed on your system and the Beboist plugin is installed in your vendor/plugins folder:
    gem install json
    script/plugin install http://svn.intridea.com/svn/public/beboist
  2. Generate your config/bebo.yml file using
    script/generate beboist_settings
  3. Fill in your appropriate app settings in config/bebo.yml. Ensure that your app name is right.
  4. Generate the first migration for your users table using:
    script/generate beboist_user_migration
  5. Migrate your database using
    rake db:migrate
  6. In your application.rb, insert the following filters:
    before_filter :reject_unadded_users
    before_filter :find_bebo_user
  7. Write your app, and keep an eye on your logs to catch any possible error messages.

API Reference

The methods listed in the Bebo API Documentation are mapped to Ruby classes in the following manner:

users.get_info(uids => "1,2,3", fields => "first_name, last_name")
  # BECOMES
BeboUsers.get_info :uids => [1,2,3], :fields => ["first_name", "last_name"]

Notes

The Beboist plugin uses Bebo’s JSON API, and the ‘json’ gem to directly convert JSON objects to Ruby. It works with Rails 2.0+, but has not been tested on Rails 1.2. Check the README for more details, and file tickets at Intridea’s Public Trac

Share:

Comment on this post (0 comments)


When You Absolutely Have To: Rails Development in Windows

Try as I might to avoid it, there comes the inevitable point in a project when I have to start doing browser compatibility. Plenty of people use VMWare Fusion or Parallels to run Windows and OS X side by side, but I find them both slow and unreliable when it comes to real testing scenarios, which leaves me with the necessity of creating a Windows development stack for Rails. After some considerable looking, I’ve settled on what I consider to be the “best” tools for the job – though they still fall short of the OS X equivalents.

  • Ruby/Rails: I use the full recommended Ruby distribution as opposed to InstantRails or similar to provide maximum flexibility and customization. I also use the MySQL Community Server for the database portion of my development stack.
  • Version Control: TortoiseSVN is a very easy to use SVN front-end, but my fingers have long since learned the console commands and continue to crave them, so I use the Apache 2.0 binaries for Windows to allow me to use SVN from the prompt.
  • Console: An absolutely indispensable application for me is Console. This open-source app provides tabbed command prompts in a much prettier interface with a number of other incredibly useful features. I highly recommend it.
  • Editor: This isn’t a slam dunk, but the closest thing to TextMate in Windows is, well, the app that was created to be TextMate for Windows. E Text Editor is very good (though in my opinion still too buggy to be called a 1.0) and comes the closest to approximating my Mac development environment. The heavier IDEs such as NetBeans and Aptana With RadRails are also viable options, but I like the speed and simplicity of E.
  • Debugging: Since the reason I end up in Windows in the first place is usually IE compatibility, I need tools to approximate the incomparable FireBug. For markup inspection, the most-helpful-least-hurtful I’ve found is Microsoft’s own Internet Explorer Developer Toolbar. Javascript debugging, the most heinous of all tasks, is made much less painful by the Microsoft Script Debugger. Don’t let the “Windows NT 4.0 and later” fool you, this is the most useful thing I’ve managed to find to get some kind of control over IE Javascript debugging.

These aren’t by any means the only tools available, and your needs/mileage may vary, but after finally getting this stack together I can develop in Windows without going into fits of hyperventilation and frustration. If you have your own indispensable tools for Rails development in Windows, I’d love to hear about them!

Share:

Comment on this post (0 comments)


Announcing 'Princely' - Rails Prince XML PDF Wrapper

Posted by on December 20th, 2007.

Recently I was implementing PDF generation for a project utilizing the fantastic library Prince XML. I came across a blog article with a basic library and helper set for Prince, which provided a great basis. I wanted to make something a little more generalized and in-keeping the Rails Way, so I have created ‘Princely’, a simple wrapper utilizing much of the code from the SubImage library but giving it better helpers and pluginizing its inclusion.

Installation

The first step is to download Prince and install it on your platform of choice (only Linux and Mac OS X supported by the plugin at this time). Next, simply install the plugin:

script/install plugin http://svn.intridea.com/svn/public/princely

You are now ready to get started using Princely to generate PDF. Note that Princely is only compatible with Rails >= 2.0

Usage

Princely uses the MimeTypes and respond_to blocks from Rails 2.0 to add PDF as a render option and a format. Because of this, it’s incredibly easy to implement a PDF! Simply make your XHTML or XML template and use pdf as the format (e.g. show.pdf.erb), then add code similar to this in your controller:

class Page < ApplicationController
  def show
    respond_to do |format|
      format.html
      format.pdf { 
        render :pdf => @page.pdf_name,
               :template => "show.pdf.erb", # not required, shown for example
               :layout => false             # not required
      }
    end
  end
end

And that’s all there is to it! If you add a .pdf to your properly routed path, you should be presented with a PDF version of the page generated by Prince. The README has more detailed usage information.

As always, there is a Trac available for any bugs or patches you might come across.

Share:

Comment on this post (0 comments)


Announcing 'Browserized Styles'

Browser compatibility, the web designer’s nightmare, has always seemed more difficult than it has to be. Why hasn’t there been an industry-standard, simple way to target CSS to specific browsers, allowing one to style the page properly without worrying about hacks and other difficult ways of pulling all the information together? I thought that something should be done about it, so taking Richard Livsey’s ‘browser_detect’ plugin as a starting point, I developed an automatic solution for including browser-specific stylesheets.

Browserized Styles provides a dead simple way to create browser-specific CSS code for use in a Rails application. All you need to do is create a .css file targeted to a browser by appending an underscore and identifier to the end.

Installation


script/plugin install http://svn.intridea.com/svn/public/browserized_styles

Example

Let’s say I have some complex CSS code that looks bad in some browsers, but works in others. Let’s also say that i’ve put it into a stylesheet in stylesheets/complex.css.

My stylesheet link tag looks something like this:


<%= stylesheet_link_tag 'complex' %>

Now all I have to do to target a browser is create a new CSS file with the browser’s identifier appended to it with an underscore (e.g. “complex_ie6.css”). That’s it! The same exact stylesheet link tag will automatically check the current user agent and load a browser-specific CSS file if it exists. Ta-da! One-step browser styles!

More information is available in the readme, but the end result is browser-targeting bliss.

The plugin is brand new and will probably see some modifications in the future. If you run into any problems or come up with a patch, feel free to submit it to the Intridea Public Trac .

Share:

Comment on this post (0 comments)


Announcing 'acts_as_taggable_on'

For a number of applications, especially our Social Networking Platform I’ve found a need for advanced tagging functionality not offered by the acts_as_taggable_on_steroids plugin. Namely, there have been a number of times when I’ve wished a model could have multiple “sets” of tags that would function both independently and together. For example, a user might have tagged themselves, but they might also have skills, interests or sports that would also function like tags. That’s where acts_as_taggable_on comes in.

Installation

To install the plugin, simply get it straight from our public SVN repository:

script/plugin install http://svn.intridea.com/svn/public/acts_as_taggable_on/

Then you will need to generate the migration for tags and taggings. This should do the trick:

script/generate acts_as_taggable_on_migration

Usage

Acts As Taggable On provides the same functionality of acts_as_taggable_on_steroids with the addition of the notion of “contexts,” or scoped areas in which taggings can live. For the user example listed above, I can now simply make a call like so:

class User < ActiveRecord::Base
  acts_as_taggable_on :tags, :skills, :interests, :sports
end

By taking the same one-liner tack as previous implementations, we are now able to set, find, retrieve, and calculate information based on tags within a context as well as as a whole. With the user model we just created:

@user = User.new(:name => "Bobby")
@user.tag_list = "awesome, slick, hefty"      # this should be familiar
@user.skill_list = "joking, clowning, boxing" # but you can do it for any context!
@user.skill_list # => ["joking","clowning","boxing"] as TagList
@user.save

@user.tags # => [<Tag name:"awesome">,<Tag name:"slick">,<Tag name:"hefty">]
@user.skills # => [<Tag name:"joking">,<Tag name:"clowning">,<Tag name:"boxing">]

User.find_tagged_with("awesome") # => [@user]
User.find_tagged_with("joking") # => [@user]
User.find_tagged_with("awesome", :on => :tags) # => [@user]
User.find_tagged_with("awesome", :on => :skills) # => []

@frankie = User.create(:name => "Frankie", :skill_list => "joking, flying, eating")
User.skill_counts # => [<Tag name="joking" count=2>,<Tag name="clowning" count=1>...]

@bobby.skill_counts
@frankie.skill_counts

And that’s all there is to it! Now you can scope your tags to whatever arbitrary name you would like. The inflector is used to create the singular/plural methods, so be careful about making sure that your nomenclature uses plurals in the acts_as_taggable_on call.

As a side note, this is meant to be used in place of acts_as_taggable_on_steroids, and the acts_as_taggable method works in acts_as_taggable_on simply by calling acts_as_taggable_on :tags. Caching has been written into the implementation but is not yet tested or verified to be working. Stay tuned for additional improvements to this plugin, and feel free to submit any bugs or patches to the Intridea Open Source Trac

Share:

Comment on this post (25 comments)


Use 'link_to_remote' unobtrusively

I have become a big believer in unobtrusive scripting utilizing lowpro, but I still like being able to use the Rails Prototype helpers because they are there and simple (not to mention hooked into plugins such as Redbox). But by default, the href on a link_to_remote is set to ’#’, which hardly gives the desired behavior when Javascript is disabled. However, with a quick rewrite of the link_to_remote helper, we can achieve unobtrusiveness (if not complete code separation) for any link_to_remote call:

def link_to_remote(name, options = {}, html_options = {})
    html_options.merge!({:href => url_for(options[:url])}) unless options[:url].blank?
    super(name, options, html_options)
end

Link_to_remote is actually just a wrapper on link_to_function, which accepts html options. However, if you set href in the html_options hash, it will override the default ’#’ and use the url specified. Now whether javascript is enabled or not, the same URL will be called. Respond_to to the rescue! Just drop some custom code into the action to which you are linking, and you can easily render out an HTML page or perform javascript behavior, depending on the format desired:

class SomeController < ApplicationController
  def some_action
    respond_to do |format|
      format.html { redirect_to :back } # reload the page we were just on
      format.js { render :update do |page| 
        # update the content dynamically
      end }
    end
  end
end

It’s a simple technique, but this has allowed me to use redboxes for modal controls and seamlessly degrade to a properly laid out form if javascript is disabled, all without changing a single line of code in the redbox plugin.

Share:

Comment on this post (0 comments)


Two from Intridea in Top Ten of October Rails Hackfest

Posted by on November 11th, 2007.

Josh Owens and Dave Naffis were the 7th and 8th leading contributors, respectively, in the October '07 Rails Hackfest. The Rails Hackfest recognizes developers who, by submitting patches, documentation, tests, and/or tickets, are actively involved in improving Ruby on Rails. Kudos to Josh and Dave for their accomplishment! Intridea is proud to give back to the Rails community, as well as other open source projects.


Share:

Comment on this post (0 comments)


OpenSocial, Buzz and the Tao of Releasing an API

Posted by on November 3rd, 2007.

Michael Arrington announced OpenSocial on TechCrunch two days before its official release. Prior to that, there were whispers everywhere about Google’s new social platform, but not many seemed to know what exactly was about to go down. Needless to say, this is good buzz. Two days before ‘launch’ the overwhelming mood among web developers, especially us who dwell in the realms of social networking, was one of intense (even feverish at some points) anticipation. What unfolded over the next few days, combined with what we observed of Facebook’s API venture, provides us a set of best practices that we can apply to an API release.


Continue reading this post

Share:

Comment on this post (0 comments)