Currently many of the persistence methods all have different behaviours when it comes to whether setters are called, and validations and or callbacks are run, Knowing what happens requires deeper knowledge of rails than just reading the method name
This can be confusing for newcomers and even people very familiar with rails will need to double check which does what.
save(validate: false) => callbacks: yes, validations: no, only_save_mentioned_columns: N/A
save => callbacks: yes, validations: yes, touch: yes, only_save_mentioned_columns: N/A
save(touch: false) => callbacks: yes, validations: yes, touch: no, only_save_mentioned_columns: N/A
save(validate: false, touch: false) => callbacks: yes, validations: no, touch: no, only_save_mentioned_columns: N/A
update/update_attributes => callbacks: yes, validations: yes, setters: yes, touch: yes, only_save_mentioned_columns: no
update_columns/update_column => callbacks: no, validations: no, setters: no, touch: no, only_save_mentioned_columns: yes
update_attribute => callbacks: yes, validations: no, setters: yes, touch: yes, only_save_mentioned_columns: no
increment!/decrement!/toggle! => callbacks: no, validations: no, setters: no, touch: no, only_save_mentioned_columns: yes
increment!/decrement!(touch: true) => callbacks: no, validations: no, setters: no, touch: yes, only_save_mentioned_columns: yes
touch => callbacks: some, validations: no, setters: no, touch: yes, only_save_mentioned_columns: yes
update_all/Class update => callbacks: no, validations: no, setters: no, touch: no, only_save_mentioned_columns: yes
Proposal A:
Follow what the save
pattern started, and provide explicit instructions to update, and a more complete list to save
-
Add
callbacks: false
option to save. -
Add
validate:
,touch:
,callbacks:
,only_save_mentioned_columns:
to update, with the option of providing the instructions in a separate hash for models where those are columns/attributes
e.g. update(column: whatever, callbacks: false)
, or update(**params, callbacks: false)
or update({ column: whatever }, callbacks: false)
, or update(params, callbacks: false)
-
deprecate the other update_* methods
-
always use attributes/setters. if one wants to not use the setters, don’t use these pretty methods, and instead use =/write_attribute and then save
-
only_save_mentioned_columns is a bad name, but I’m having difficulty thinking of a better one that’s as clear
-
validate the keyword arguments passed to save/update, so people don’t accidentally write ‘skip_callbacks: true’ or ‘validates: false’ or etc
Proposal B:
Rather than modifying update_*/save signatures, deprecate and replace with a method called persist
and persist!
that takes those options
I’d be happy to undertake the work of doing this PR if this is something you’d be interested in merging