You must be very careful when create "before_*" callbacks in Rails.
I found one interesting feature (of course it is not bug :D ) ActiveRecord raise with error RecordNotSaved if you have "before_*" callback that return "false". For example:
class User < ActiveRecord::Base before_save :set_short_link private def set_short_link short_link = name.to_url if name.changed? end end
You can`t save instance of this class if you don`t change "name" because method "set_short_link" return false (see /activerecord/lib/active_record/base.rb, line 2568)
Right version will be:
class User < ActiveRecord::Base before_save :set_short_link private def set_short_link short_link = name.to_url if name.changed? true end end
You are right, but in this case you save time only on url generation. I'm considering the url will be always the same for unique name and you don't use slug table to track all slugs (like slugged do). I think that following code will be more readable and it also protect from empty urls as a bonus
ReplyDeletedef set_short_link
short_link = name.to_url
end
Moreover you should use self to specify your intentions to change attribute value instead of to arrange local variable, so the final solution I'd like to use is
def set_short_link
self.short_link = name.to_url
end
Thanks for reply.
ReplyDeleteBut... this is a fiction example. I never wrote this code. I just try to tell about interesting features that i found in before_* callbacks.
Yes, I see, but using explicit return just true/false from callback looks odd for me. Definitely it should be documented (with something like "# cancel callback and abort saving"
ReplyDeleteBut maybe I think so because I rarely use this feature (in spite of it's the only documented way to canceling callbacks)