RudyGems

Matthew Rudy Jacobs
see me swim
Github
see some of my code
WorkingWithRails
see me working with rails

has_one_accessor

HasOneAccessor is a plugin for ActiveRecord that solves the problem of having associations that act like a attribute.

Perhaps only a few users have an openid, so it doesn’t make sense to add an :open_id_url column to your :users table.

Instead you create a new model OpenId

class OpenId < ActiveRecord::Base
  belong_to :user
end

class User < ActiveRecord::Base
  has_one :open_id

  def open_id_url
    self.open_id && self.open_id.url
  end

  def open_id_url=(value)
    if value.blank?
      self.open_id && self.open_id = nil
    else
      self.open_id || self.build_open_id
      self.open_id.url = value
    end
  end
end

Now, that’s not too bad. But maybe you didn’t have time to clean it up.

Maybe you deal with it in your controller.

def update
  if params[:open_id_url] && params[:open_id_url].present?
    @user.open_id || @user.build_open_id
    @user.open_id.url = params[:open_id_url]
  end
  ...
end

Now, that’s all fine.

But we all want to make these things easier.

We all want to cast as much code aside.

ConventionOverConfiguration and all that.

Enter has_one_accessor

class OpenId < ActiveRecord::Base
  belong_to :user
end

class User < ActiveRecord::Base
  has_one :open_id
  has_one_accessor :open_id, :url, :allow_blank => false
end

This takes away all the code,

This takes care of building a record if there wasn’t one, of only saving it when you save the User.

It even kills the association if the value is :blank? (if you pass in :allow_blank => false).

B00m, h34dsh0t?

Comments (View)
blog comments powered by Disqus