Reputation: 113
I recently upgraded a rails 3 application to rails 4. When I am trying to create a new Test, below code from before_save fails to execute. The same code works fine with rails 3.
class Test < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
before_save do
if code_changed?
self.assignments.each{|a| a.touch}
end
end
end
class Assignment < ActiveRecord::Base
belongs_to :test, :touch => true
end
I see the below error when I create a new test.
ActiveRecord::ActiveRecordError (cannot touch on a new record object):
app/models/test.rb:6:in `block (2 levels) in <class:Test>'
app/models/test.rb:6:in `block in <class:Test>'
app/controllers/tests_controller.rb:423:in `create'
Any suggestions to resolve this issue ??
Upvotes: 2
Views: 1838
Reputation: 435
It is because your function that is before save needs to be private. And you can restructure it like this for readability.
class Test < ActiveRecord::Base
has_many :assignments, :dependent => :destroy
before_save :before_save_function
private
def before_save_function
if code_changed?
self.assignments.each{|a| a.touch}
end
end
end
Cheers! Hope it Helps.
Upvotes: 0
Reputation: 7288
The error is raised because there is a new assignment object and not saved in the database. The touch can not be called on new record.
Just check for new_record? before calling touch.
before_save do
if code_changed?
self.assignments.each{|a| a.touch unless a.new_record?}
end
end
Upvotes: 3