简体   繁体   中英

Update a rails parent record with information from the child record upon creation

this is my first post so I'm not exactly sure how to format this. Lmk if I'm doing anything wrong.

I'm fairly new to rails and I am making an app that basically just allows users to submit 'grimes' (which you can think of as reviews) for other users. The app has two basic models: users and grimes.

User Model:

class User < ApplicationRecord
    has_many :grimes
end

Grimes Model:

class Grime < ApplicationRecord
  belongs_to :user
  validates :user, presence: true
end

each grime has a griminess attribute, which is basically the rating from 1-5 for the grime. Each user also has a griminess attribute, which I would like to be the sum of the griminess of each of a user's associated grimes. ie. if user1 has two grimes, g1 with griminess 3 and g2 with griminess 2, then user1 griminess should be 5.

I could do this by iterating through each of the user's grimes when I would like to display the user's griminess, but that seems very unnecessary. Instead, I would like to just increment the user's griminess each time a new grime associated with them is added, but I can't figure out how to do that right now.

the form to create a grime looks like this:

<%= form_for @grime do |f| %>
    Title: <%= f.text_field :title %><br />
    Description: <%= f.text_area :description %><br />
    Griminess Level:  <%= f.select :griminess, (0..5) %>
    Select Grimer: <%= f.collection_select(:user_id, User.all, :id, :name) %><br />
    <%= f.submit %>
<% end %> 

and my grimes#create looks like this:

def create
      @grime = Grime.new(grime_params)
      
      if @grime.save
          flash[:success] = "Grime Saved Successfully"
          redirect_to @grime
      else
          flash[:error] = "Error: Could Not Save Grime!"
          render :new
      end
  end

I feel like I should be able to do something like @grime.user.griminess += @grime.griminess in the create method, but that doesn't seem to work for me. Can anyone recommend a better way to approach this?

Add after_save hook in Grime which will call a method on a grime whenever that grime is saved.

class Grime < ApplicationRecord
  after_save :update_user_griminess # register the callback
  belongs_to :user
  validates :user, presence: true

  #callback body
  def update_user_griminess
    user.griminess = user.grimes.sum(:griminess) # update user griminess as sum of it's all grimes' griminess 
    user.save
  end      
end

There is an alternative after_create hook in ActiveRecord which runs just once when the object is created for the first time, but I preferred after_save here to adjust for cases when a grime 's griminess is updated.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM