class User < ActiveRecord::Base
has_one :profile
def create_from_ldap(login)
#some code left out
create_personal_belongings
save
end
def create_personal_belongings
profile = Personal::Profile.new
profile.id = self.id
profile.save!
end
end
into these lines of code:
class User < ActiveRecord::Base
has_one :profile
after_create :create_profile
def create_from_ldap(login)
#some code left out
save
end
end
Consequence of this change was that a user profile is always created when a user is created. Which is great, because users without a profile should not exist anyway. But it broke some specs, because some specs relied on specifying a certain profile for a user, so we can test some aspects of the user / profile relationship properly. So what I actually wanted to do, is create a profile after creating a user, but only if the user hasn't got a profile yet.
When using active_record validations I've discovered you can do a conditional validation like this:
class User < ActiveRecord::Base validates :email, :presence => true, :email => true, :if => :has_email_enabled? endThis validates the user's email attribute only if the has_email_enabled? method returns true for the specific user object. (see the active_record_validations documentation for more info) I couldn't find if I can also use conditionals on active_record lifecycle callbacks, so I just tried:
class User < ActiveRecord::Base
has_one :profile
after_create :create_profile, :unless => :profile
def create_from_ldap(login)
#some code left out
save
end
end
Hey, that works! I believe it's not a documented feature, but it's really nice. I love Rails' adagium "use convention over configuration", because once you know how some stuff works in Rails, you can deduct how the other stuff works. And even better, the chosen conventions usually make sense. To me, at least.
No comments:
Post a Comment