Search code examples
ruby-on-railsruby-on-rails-4callbackbefore-save

Rails calculated value not working on checkboxes


The extra costs column in the Reservation model doesn't get calculated and saved on creating a new reservation. It's getting calculated and saved when the reservation is edited (even without changing any values in the form). It seems the checkboxes values are not being received by the calculate method or something.

Reservation has_many :bookings, has_many :extras, :through => :bookings
Booking belongs_to :extra, belongs_to :reservation
Extra has_many :bookings, has_many :reservations, :through => :bookings

before_save :calculate_extras_cost

def calculate_extras_cost 
  self.extras_cost = self.extras.sum(:daily_rate) * total_days  
end

<%=hidden_field_tag "reservation[extra_ids][]", nil %> 
<%Extra.all.each do |extra|%>
  <%= check_box_tag "reservation[extra_ids][]", extra.id, @reservation.extra_ids.include?(extra.id), id: dom_id(extra)%>
<% end %>

Solution

  • Use the form collection helpers instead of creating the inputs manually:

    <%= form_for(@reservation) do |f| %>
      <%= f.collection_check_boxes(:extra_ids, Extra.all, :id, :name) %>
    <% end %>
    

    Also make sure you are whitelisting the :extra_ids property.

    One other thing to bear in mind when using callbacks is that the parent record must be inserted into the database before the child records! That means you cannot use self.extras.sum(:daily_rate) in the callback because it relies on the child records being in the database.

    You could use self.extras.map(&:daily_rate).sum to sum the values of the associated models from memory in Ruby. Another option would be to use association callbacks.