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?