Reputation: 8843
I am new to Rails and can get this right.
Trying to update "completed_at" when "completed" turns true.
I've read this: https://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changed-3F
And decided to add a callback, on each update or save. Then check if the "completed" prop has changed, if not, if it is true, update "completed_at" to the current date.
The method "check_is_completed" does get called, but I can't access the correct prop's and detect if changed and get the new value
class Task < ApplicationRecord
belongs_to :user
validates :name, presence: true
after_save :check_is_completed
after_update :check_is_completed
private
# This gets called
def check_is_completed
# try 1
# This does not work called
if @completed.changed?
if @completed == true
self.completed_at = Date.new()
end
end
#try 2
if self.completed_changed?
if self.completed == true
self.completed_at = Date.new()
end
end
end
end
Upvotes: 2
Views: 1495
Reputation: 6455
You're pretty much there. Your issue is that you're performing your check after you save instead of before. After you've saved the record, the update has already taken place, so the system thinks nothing has changed.
Change
after_save :check_is_completed
after_update :check_is_completed
To
before_save :check_is_completed
You also won't need to use any instance variables. As you're already in your class, all you need to do is:
def check_is_completed
return unless completed_changed?
self.completed_at = Date.new() if completed?
end
This will perform the check before every save, doing nothing unless the completed attribute has changed, and then only updating the completed_at field if completed is true
Upvotes: 5