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


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)


Intridea Helps Launch VisualCV

Posted by on February 11th, 2008.

Intridea is pleased to announce the beta launch of VisualCV (http://www.visualcv.com). Intridea has been working closely with VisualCV for several months to develop their breakthrough site and bring it to market. VisualCV reinvents the paper resume into a dynamic career management tool by incorporating images, audio, and video alongside traditional resume content.

Intridea partnered with VisualCV because we believe their approach will revolutionize the way companies and professionals interact. Using cutting-edge Internet technologies, we worked with VisualCV to build a unique platform that delivers highly interactive user experience as well as a secure mechanism for sharing resume content. VisualCV partnered with Intridea because of the national reputation we've earned for our agile Ruby on Rails practices.

Check out www.VisualCV.com now

[UPDATE]

VisualCV has been generating a lot of media buzz so far - check out some of the coverage below:

Share:

Comment on this post (0 comments)