The book model is associated with the user via rate (with the rating field).

I want to make it so that when creating a new 'rate', the average value for the book is recalculated and recorded in the "book" field av_rating . I tried this:

 def create @new_rate = @book.rates.build(rate_params) @new_rate.user = current_user if @new_rate.save @book.av_rating = Rate.where(book_id: @book.id).average(:rating) redirect_to @book else ... 

The field remains empty

  • one
    where do you save this @book.av_rating after save? - Manuk Karapetyan
  • @book , too, must be saved, if changed. - D-side

2 answers 2

Since you assign an attribute value to an object in memory, the value does not fall into the database and is not saved. As an alternative to the already mentioned explicit call to the save method of the model, you can use the update method, which leads to the explicit saving of the new value to the database

 def create @new_rate = @book.rates.build(rate_params) @new_rate.user = current_user if @new_rate.save @book.update(av_rating: Rate.where(book_id: @book.id).average(:rating)) redirect_to @book else ... 

    From this piece of code you can see that you change the rating but do not save to the database. In this case, you just need to make another save for the @book object

     if @new_rate.save @book.av_rating = Rate.where(book_id: @book.id).average(:rating) @book.save redirect_to @book else