Before_validation:更新和保持连续性

时间:2012-02-23 15:11:50

标签: ruby-on-rails ruby-on-rails-3 validation datatable

我有一个简单的工作计划rails应用程序。计划中的工作将按工作的优先顺序排序。由于某些作业可能会优先级发生变化,并且性质相同,需要完成它们的顺序,我需要能够更新表的其余部分的优先级和优先级,以确保没有2个作业共享相同的优先级。一旦优先级更新,我希望它使优先级列表是连续的,换句话说,优先级标记为1,2,3,4,5等。而不是像1,2,4,5,6,8等间隙。

有人可以帮我找出正确的编码来实现这个目标吗?

这是我目前在我的模型中所拥有的:

class Job < ActiveRecord::Base
  include ActiveModel::Dirty
  belongs_to :customer
  has_many :job_items

  before_validation :update_priorities

  validates :priority, :uniqueness => true

  private

  def update_priorities
  if self.priority_changed?
    self.class.where("priority >= ?", self.priority).update_all("priority = priority + 1")
  else
    nil  
  end
end

如果上述代码是一项全新的工作,则会更新优先级。但是,一旦我开始重新排序当前作业,序列中就会出现间隙。

我目前正在使用Rails 3.2.1

2 个答案:

答案 0 :(得分:1)

你在这里寻找的是acts_as_list,它会自动为你做这件事。例如,如果您正在创建一个新工作,并且您想要一个特定的位置:

@job = Job.create
@job.insert_at(2) # will automatically insert your job at position 2, moving all other items in the list according.

要查看acts_as_list为您提供的所有方法check out the comments in the source

答案 1 :(得分:0)

我尝试过Veraticus提供的acts_as_list,但它对我的应用程序来说无法正常工作。在摆弄它之后,我将我的代码更改为以下内容,它就像我需要它一样工作。

  def update_priorities
if self.priority_changed?
  if self.priority < self.priority_was
    self.class.where("priority >= ?", self.priority).update_all("priority = priority + 1")
    self.class.where("priority > ?", self.priority_was).update_all("priority = priority - 1")
  else
    nil
  end
  if self.priority > self.priority_was
    self.class.where("priority <= ?", self.priority).update_all("priority = priority - 1")
    self.class.where("priority < ?", self.priority_was).update_all("priority = priority + 1")
  else
    nil
  end
end