before_save do @old_pictures_size = pictures.size end
Well, the value is calculated before saving. If up to this point were added (but not saved) images for example via bike.pictures << Picture.new) then they are already in the collection and will be counted.
The easiest (but not the most correct) is to move this into after_initialize .
I also want to note that a comparison by the number of pictures is not the best way to check whether they were added. Example: I create a Bike , then edit it, delete the old image and add a new one. The number of pictures has not changed, but you need to moderate it again.
In addition, callbacks and nested attributes are very difficult to control and maintain. More correctly, in this case, use FormObject . And Virtus can help create such objects. I cannot make a prototype for a specific case - there is too little data (you need an understanding of what is happening in Picture , the controller and how else you plan to use old_pictures_size ). Here is an example of such an object for the general case.
UPD
We found out that the pictures are added separately. Here is FormObject 's example:
class BikeForm include ActiveModel::Validations include ActiveModel::Conversion include Virtus.model(constructor: false) attribute :id, Integer, writer: :private attribute :title, String attribute :description, String attribute :picture_ids, Array[Integer] # дефолтное значение взял с потолка. Главное чтобы не было moderation attribute :status, String, writer: :private, default: "confirmed" def initialize(bike = nil) set_default_attributes return unless bike self.attributes = bike.slice(:title, :description, :picture_ids) self.id = bike.id end # Аналогичные сеттеры можно переопределить и для других аттрибутов def picture_ids=(new_picture_ids) self.status = :moderation super end def save return false unless valid? bike.attributes = attributes bike.save end private def bike @bike ||= id ? Bike.find(id) : Bike.new end end
In this way, we get rid of callbacks, when the significant attributes change, the object will automatically be sent to moderation.
:pictures, as I understand it, although it is recorded after the main record, but everything - should be urinated to upgrade, i.e. write:pictureson the idea should bechanged: true. Ie it will lead accordingly to thepictures_changed?: true- Mal Skrylev