Jeremy B
Jeremy B

Reputation: 911

Execution Order In a Method with Rails

I have a question regarding the execution order in a Rails method : Here what I do in my model :

def update_fields
  FillMethods.fill_info("BadgeUser", "Badge", self.id, self.badge_id, "badge_")
  self.reload
  self.update_attributes(:completed => true) if self.badge_goal == 0
end

I have an object, then I apply the FillMethods info on it to fill some fields in this object and save it. Then I want to check if badge_goal == 0 to mark it as completed.

The issue I have is that if I don't put self.reload the self item will not be updated, the object will be in the database but the self item will be the same as before the FillMethods. If I do self.reload the self item is correct and it can be marked as completed correctly

My question is will ruby wait for the FIllMethods to be done to reload the self or it will reload the self before the FillMethods is done ?

Why does the self item is not correct if I don't do self.reload ? The FillMethods is a module in my lib directory.

Thanks for your help,

Thats my fill method :

module FillMethods

def self.fill_info(model1, model2, id1, id2, string)
  parameters1 = model1.constantize.attr_accessible[:default].to_a.map {|s| s.dup}
  parameters1.delete_if {|s| !s.start_with?(string)}
  parameters2 = parameters1.map {|s| s = s.split(string)[1]}

  h = Hash[parameters1.zip parameters2]
  object1 = model1.constantize.find(id1)
  object2 = model2.constantize.find(id2)

  h.each do |parameter1, parameter2|
    object1.update_attribute(parameter1.to_sym , object2.send(parameter2))
  end
    return object1
end

end

The goal of the method is to fill the BadgeUser table with all the badge info. For each column in my Badge table (like name) I have in my BadgeUser table badge_name

Thanks,

Upvotes: 0

Views: 716

Answers (1)

giorgian
giorgian

Reputation: 3825

I cannot be sure without seeing the code, but judging from the parameters you pass, I guess that FillMethods.fill_info retrieves the record from db again, using the third parameter id. It then changes the record and stores it back.

Your object (self) has no way, under ActiveRecord or similar, to know that the db was modified somewhere somehow.

Note that you are retrieving the same record from db some three times instead than once.

If you change FillMethods.fill_info to instead accept a record (self itself), and modify it, then self would be in the new state.

Addendum

Ruby code is executed sequentially in a single thread unless you explicitly start a new thread, so yes, .fill_info is executed before continuing with the rest of update_fields.

Upvotes: 1

Related Questions