Legacy association data on an instance of an ActiveRecord model?

I use Rails 2 and I have a one-to-many association between the model Projectand the model Schedulein this application.

I have an observer check when the attributes of different things change, and in response, it iterates over an array of hashes with which you can fill in new instances Schedule.

Each instance Schedulemust have an attribute disp_orderthat ultimately tells the front end where to display it, showing them in a list. disp_orderIt is filled by adding a schedule to the project, so that it is equal to one greater than the current one disp_order.

The problem is iteration in the observer. When I Scheduleiterate over an array of hashes filled with data , each time through iteration I should calculate disp_orderas one higher than the previous one to account for the added one Schedule. However, in practice this is not the case if I do not update the object Projectin the middle of the iteration with project = Project.find(project.id), otherwise the same maximum value disp_orders is computed all the same and not executed. You have an exact list of these Scheduleinstances.

Is there a better way to do this? (Note: I mean, there is a better way so that I cannot say that the project will find itself again. There are several places in which I actively clear the rest of the code that follows, but there is a question for this. I am only interested in this line and everything that affects it.)

project.rb

class Project < ActiveRecord::Base
  # ...
  has_many :schedules, :dependent => :destroy
  # ...
  belongs_to :data, :polymorphic => true, :dependent => :destroy
    accepts_nested_attributes_for :data
  # ...

schedule.rb

class Schedule < ActiveRecord::Base
  belongs_to :project, :include => [:data]
  # ...

project_event_observer.rb

class ProjectEventObserver < ActiveRecord::Observer
  # ...          
  def perform_actions(project, actions)
    # ...
    actions.each { |action|
      action.each { |a_type, action_list|
        action_list.each { |action_data|
          self.send(action_type.to_s.singularize, action_data, project)
          project = Project.find(project.id) #My question is about this line.
        }
      }
    }
  # ...

[    
  {:add_tasks => [
    {:name => "Do a thing", :section => "General"},
    {:name => "Do another thing", :section => "General"},
   ]
  },
  # More like this one.
]

,

def add_task(hash, project)
  # ...
  sched = Schedule.new
  hash.each { |key, val|
    # ...
    sched.write_attribute(key, val)
    # ...
  }
  sched.add_to(project)
end

schedule.rb

def add_to(proj)
  schedules = proj.schedules
  return if schedules.map(&:name).include?(self.name)
  section_tasks = schedules.select{|sched| sched.section == self.section}
  if section_tasks.empty?
    self.disp_order = 1
  else
    self.disp_order = section_tasks.map(&:disp_order).max + 1 #always display after previously existing schedules
  end
  self.project = proj
  self.save
end
+4
1

, .

.

true add_to , .

inverse_of, , , .

+3

Source: https://habr.com/ru/post/1540800/


All Articles