2012-02-23 63 views
0

我有一個簡單的工作計劃rails應用程序。時間表中的工作將按照工作的優先級排序。由於一些工作可能會改變優先級,並且性質相同,所以需要完成它們的順序,我需要能夠更新表的其餘部分的優先級和優先級,以確保沒有2個工作共享相同的優先級。一旦優先級更新,我希望它使優先級列表是連續的,換句話說,優先級標記爲1,2,3,4,5等。而不是像1,2,4,5,6,8等差距。Before_validation:更新和保持連續性

有人可以幫我找出適當的代碼來實現這一目標嗎?

這是我目前在我的模型:

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

回答

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 

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方法。

+0

這可能是。看看他們在註釋掉的代碼中使用的代碼和示例,似乎我需要一個主類來環繞作業。如果那是真的,那麼它不會爲我工作。 – 2012-02-23 17:19:58

+0

我想你可以通過不提供範圍來使用它,而不需要包裝類。所以只需在模型中調用acts_as_list:column =>'priority'',它應該提供所有acts_as_list的魔法,而不需要作用域。 – Veraticus 2012-02-23 17:22:21

+0

我可能是錯的,但我認爲它確實需要大師班。我不認爲它知道如何調整其餘的工作,而不涉及大師班。 – 2012-02-23 20:04:46