Can I, or should I, use a callback to create an associated record in Rails? Also, if either record creation or update fails will both records not be saved in the database?
The idea behind this solution is to DRY up the code.
If so, should I use after_save
or something else? If I should use after_save
, is the example below sufficient or do I need to raise an error or do something else?
I am aware of gems like papertrail that will do something like this but this is not the solution we need.
Example:
class Fruit < ApplicationRecord
end
class Apple < ApplicationRecord
after_save :create_fruit
def create_fruit
Fruit.create!(item_id: self.id)
end
end
It seems that there will be a rollback and both records will not be saved based on this answer and here. I do believe this answer may help also but still think I need to ask this question at the moment. Will my example rollback if there is an issue with either record update or creation?
You don't need a callback.
If you just setup an association between the two models you can create both at once:
class Fruit < ApplicationRecord
belongs_to :item, polymorphic: true
end
class Apple < ApplicationRecord
has_one :fruit, as: :item
end
apple = Apple.new
apple.build_fruit
apple.save
This will create both in a transaction. If you want to fire the validations on Fruit
you can use validates_associated
:
class Apple < ApplicationRecord
has_one :fruit, as: :item
validates_assocatiated :item
end
Sure you could wrap this process into a callback - but just do it explicitly for now and refactor when and if you actually need it as callbacks come with their own set of drawbacks.