SocialSpring - introducing the world's most advanced white-label social networking platform

Posted by on May 1st, 2008.

Intridea is pleased to announce the official release of SocialSpring, the world's most advanced white-label social networking platform. SocialSpring provides enterprise-grade solutions for social networking. Built on a modular and extensible platform, SocialSpring powered networks can easily integrate everything from photos and videos to forums and community questions. With an impressive list of features, Social Spring can power any social community.

See it in action! SocialSpring is the base of our Ruby community launched this week - Acts As Community - and we also have a demo installation available.

For more information, please visit http://www.socialspring.com

Share:

Comment on this post (0 comments)


Acts As Community: The Social Network for Rubyists

Posted by on April 30th, 2008.

We are proud to announce today the official launch of Acts As Community. Acts As Community is a social network built on Intridea’s SocialSpring Platform for Ruby enthusiasts of all kinds (including Rails Developers, Merbivores, and those beyond the web app realm). Our goal is to provide a centralized resource for Ruby developers everywhere to gather and interact.

We’re very excited about the potential for the site. Right now, you can organize groups and events, share questions and code snippets as well as photos, videos and your blog’s RSS feed, and post job listings for interested Rubyists. We will also be continuing to roll out new features with a focus on open source and community development. The most important part of any social network, however, is you, the users! We hope you find the site useful and take part in the construction of a new community.

Share:

Comment on this post (0 comments)


From Param: How URL-Based Fetching Ought to Be

The addition of RESTful routing and the #to_param method in Rails has undoubtedly improved both the ease and usefulness of URL generation in Rails apps. However, there has come to be a rather insidious tendency to have an auto-generated id as the true reference for a given item. This may make sense for some or even many apps, but by and large records should be referred to by their content, not their ids, in URLs if at all possible. With this goal in mind, I have released from_param, a simple addition to ActiveRecord that makes it dead simple to use better URL finders.

Example

First of all, from_param is meant to simply be the complement of to_param, that is, you should be able to pass Model.from_param(some_parameter) the same way you would pass Model.from_xml(some_xml). Let’s examine how this works in practice:

class User < ActiveRecord::Base
  def to_param
    "#{id}-#{login.downcase}" 
  end
end

class UsersController < ApplicationController
  # GET /users/1-mbleigh
  def show
    @user = User.from_param(params[:id]) # => <User id=1 login="mbleigh">
  end
end

Simple enough, and it should look very familiar except that instead of a User.find or User.find_by_id, we have User.from_param. In fact, that’s exactly what this code does: from_param by default will call find_by_id since that is how the default to_param is configured.

Now let’s take something a little more complicated: a blog post title. I definitely don’t want an id in the URL if it’s a permalink, so how can I make an arbitrary parameter found as easily as the id? Simple, just add a param column to your table! Take a look:

class Post < ActiveRecord::Base
  def to_param
    "#{created_at.strftime("%Y-%m-%d")}-#{title.gsub(" ","-").downcase.gsub(/[^a-z0-9-]/,"")}" 
  end
end

class PostsController < ApplicationController
  # GET /posts/2008-04-26-from-param-plugin-released
  @post = Post.from_param(params[:id]) # => <Post title="From Param: Plugin Released" created_at="2008-04-26">
end

From Param will auto-magically save the to_param of your model to the specified parameter column (defaults to “param” but you can set it by calling set_param_column) and then automatically know to find by that column if it exists when from_param is called. This way, all you have to do is define a to_param that will be unique to your record and everything else is handled for you!

This plugin is really quite simple, but it establishes a convention that I feel has been missing from Rails for some time: a standard method to call to retrieve a record based on its URL parameter.

Installation

To install the plugin on Edge Rails or Rails 2.1 and greater:

script/plugin install git://github.com/mbleigh/from_param.git

On earlier versions of Rails:

git clone git://github.com/mbleigh/from_param.git vendor/plugins/from_param

Resources

If you have any suggestions for expanding the usefulness of the plugin or run into any problems, please report them on the From Param Lighthouse Project.

Share:

Comment on this post (1 comment)


Seed Fu: Simple Seed Data for Rails

The issue of pre-loading needed data for a Rails application has always been somewhat confusing and difficult. A great post on Rail Spikes discusses the issue in-depth and offers a number of different solutions, but ultimately they all seem just a little short of the desired simplicity. By combining a few of the ideas and adding a few of my own, I have created a seeding system that I feel is very straightforward and easy to use.

Borrowing the basic premise of the db-populate plugin, Seed Fu is based around loading ruby scripts located in db/fixtures via a Rake task. What db-populate doesn’t offer is a clear syntax for describing the records to be seeded. That’s where Seed Fu comes in.

Usage

First, just create a new ruby script in db/fixtures (and create the directory itself, obviously). Any script that you drop in this folder will be automatically run when you execute your seeding rake task. Additionally, you can load environment-specific data by adding scripts in a folder of the same name (i.e. db/fixtures/development. In these scripts you can execute arbitrary Ruby code with the full Rails environment loaded; however, you should remember that this code will be executed every time the rake task is called and should not cause duplication or destroy anything that can’t be retrieved. The syntax for Seed Fu works as follows (with a User model as an example):

# db/fixtures/users.rb
# put as many seeds as you like in

User.seed(:login, :email) do |s|
  s.login = "admin" 
  s.email = "admin@adminnerson.com" 
  s.first_name = "Bob" 
  s.last_name = "Bobson" 
end

User.seed(:login, :email) do |s|
  s.login = "michael" 
  s.email = "michael@abc.com" 
  s.first_name = "Michael" 
  s.last_name = "Bleigh" 
end

The seed method is available on any ActiveRecord. It takes as parameters the ‘constraints’ for that seeding; in other words, the fixed attributes that will not change in the record’s life. The constraints are used to find the record and update instead of creating it with the attributes provided if it already exists. This way your seeds can change without mucking with other live data on your server.

Once you have set up your fixtures, it’s simple to run them:

rake db:seed

Or if you want to run them for a targeted environment:

rake db:seed RAILS_ENV=production

Installation

In edge Rails or Rails 2.1 and beyond:

script/plugin install git://github.com/mbleigh/seed-fu.git

In previous versions of Rails:

git clone git://github.com/mbleigh/seed-fu.git vendor/plugins/seed-fu

I have some ideas for the expansion of this plugin (loading from CSV for larger datasets, etc.), so stay tuned! If you have ideas for additional features or encounter any problems, I have set up a Lighthouse project for your enjoyment.

Share:

Comment on this post (11 comments)


Mash - Mocking Hash for total poser objects

Posted by on April 12th, 2008.

There are a number of times when I need something like an OpenStruct with a little more power. Often times this is for API-esque calls that don’t merit a full on ActiveResource. I wrote a small class for use with my ruby-github library and wanted to make it a separate gem because I think it’s pretty useful to have around.

Usage

Basically a Mash is a Hash that acts a little more like a full-fledged object when it comes to the keyed values. Using Ruby’s method punctuation idioms, you can easily create pseudo-objects that store information in a clean, easy way. At a basic level this just means writing and reading arbitrary attributes, like so:

author = Mash.new
author.name # => nil
author.name = "Michael Bleigh" 
author.name # => "Michael Bleigh" 
author.email = "michael@intridea.com" 
author.inspect # => <Mock name="Michael Bleigh" email="michael@intridea.com">

So far that’s pretty much how an OpenStruct behaves. And, like an OpenStruct, you can pass in a hash and it will convert it. Unlike an OpenStruct, however, Mash will recursively descend, converting Hashes into Mashes so you can assign multiple levels from a single source hash. Take this as an example:

hash = { :author => {:name => "Michael Bleigh", :email => "michael@intridea.com"},
       :gems => [{:name => "ruby-github", :id => 1}, {:name => "mash", :id => 2}]}

mash = Mash.new(hash)
mash.author.name # => "Michael Bleigh" 
mash.gems.first.name # => "ruby-github"

This can be really useful if you have just parsed out XML or JSON into a hash and just want to dump it into a richer format. It’s just that easy! You can use the ? operator at the end to check for whether or not an attribute has already been assigned:

mash = Mash.new
mash.name? # => false
mash.name = "Michael Bleigh" 
mash.name? # => true

A final, and a little more difficult to understand, method modifier is a bang (!) at the end of the method. This essentially forces the Mash to initialize that value as a Mash if it isn’t already initialized (it will return the existing value if one does exist). Using this method, you can set ‘deep’ values without the hassle of going through many lines of code. Example:

mash = Mash.new
mash.author!.name = "Michael Bleigh" 
mash.author.info!.url = "http://www.mbleigh.com/" 
mash.inspect # => <Mash author=<Mash name="Michael Bleigh" info=<Mash url="http://www.mbleigh.com/">>>
mash.author.info.url # => "http://www.mbleigh.com/"

One final useful way to use the Mash library is by extending it! Subclassing Mash can give you some nice easy ways to create simple record-like objects:

class Person < Mash
  def full_name
    "#{first_name}#{" " if first_name? && last_name?}#{last_name}" 
  end
end

bob = Person.new(:first_name => "Bob", :last_name => "Bobson")
bob.full_name # => "Michael Bleigh"

For advanced usage that I’m not quite ready to tackle in a blog post, you can override assignment methods (such as name= and this behavior will be picked up even when the Mash is being initialized by cloning a Hash.

Installation

It’s available as a gem on Rubyforge, so your easiest method will be:

sudo gem install mash

If you prefer to clone the GitHub source directly:

git clone git://github.com/mbleigh/mash.git

This is all very simple but also very powerful. I have a number of projects that will be getting some Mashes now that I’ve written the library, and maybe you’ll find a use for it as well.

Share:

Comment on this post (7 comments)


Ruby-GitHub: Simple Access to the GitHub API

Posted by on April 1st, 2008.

While the GitHub folks have produced their own github-gem that provides some useful command-line tools for GitHub users, the library they have written isn’t your traditional API wrapper since it’s focused around using GitHub rather than getting information from GitHub.

I’ve thrown together a small library called ruby-github that provides that kind of functionality. It’s extremely simple and works with all of the currently available API but that only comes down to three read-only calls at this point. Use like so:

user = GitHub::API.user('mbleigh')
user.name # => "Michael Bleigh" 
user.repositories # => array of repositories
user.repositories.last.name # => "ruby-github" 
user.repositories.last.url # => "http://github.com/mbleigh/ruby-github" 
user.repositories.last.commits # => array of commits (see below)

commits = GitHub::API.commits('mbleigh','ruby-github')
commits.first.message # => "Moved github.rb to ruby-github.rb..." 
commits.first.id # => "1d8c21062e11bb1ecd51ab840aa13d906993f3f7" 

commit = GitHub::API.commit('mbleigh','ruby-github','1d8c21062e11bb1ecd51ab840aa13d906993f3f7')
commit.message # => "Moved github.rb to ruby-github.rb..." 
commit.added.collect{|c| c.filename} # => ["init.rb", "lib/ruby-github.rb"]

Installation

The easiest way to install ruby-github is as a gem:

gem install ruby-github

You can also install it as a Rails plugin if that’s your thing:

git clone git://github.com/mbleigh/ruby-github.git  vendor/plugins/ruby-github

Update 4/12/2008: Version 0.0.2 of the gem has been released and I have revised this post to adhere to the new gem’s requirements.

Share:

Comment on this post (1 comment)


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 (1 comment)


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)


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)


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 (1 comment)


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 on Edge Rails or Rails 2.1 and greater:

script/plugin install git://github.com/mbleigh/acts-as-taggable-on.git

On previous versions of Rails:

git clone git://github.com/mbleigh/acts-as-taggable-on.git vendor/plugins/acts-as-taggable-on

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 Lighthouse

UPDATE 5/3/07: Acts As Taggable on is now hosted on GitHub and has a public Lighthouse available for bug tracking. Information updated above.

Share:

Comment on this post (31 comments)