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 endinto 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 endConsequence 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 endHey, 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