2011-10-13 65 views
1

我有一個教程類和一個步驟類。教程有很多步驟,每一步都屬於教程。我在我的模型和路線文件中有這個設置。在教程類的show動作中,屬於該教程的所有步驟也都會加載。問題是在創建了幾個步驟後,4-6,他們將失去秩序。例如,加載的第一步是第7步,但在此之後,步驟是按順序的。我爲數據庫使用postgresql,並在gemfile中包含pg gem。 教程模式:嵌套資源無序加載

class Tutorial < ActiveRecord::Base 
    attr_accessible :name, :summary, :permalink 
    has_many :steps 

    validates :name, :presence => true, 
       :length => { :maximum => 50 }, 
       :uniqueness => { :case_sensitive => false } 

    validates :summary, :presence => true, 
      :length => { :maximum => 2000 } 

    before_create :set_up_permalink 

    def to_param 
permalink 
    end 

    private 

    def set_up_permalink 
    permalink = self.name.gsub(' ', '-').gsub(/[^a-zA-Z0-9\_\-\.]/, '') 
    self.permalink = permalink 
end 

步驟模型:

class Step < ActiveRecord::Base 
    attr_accessible :tutorial_id, :body, :position 
    belongs_to :tutorial 

    validates :body, :presence => true 

    before_create :assign_position 

    private 

    def assign_position 
@tutorial = self.tutorial 
@position = @tutorial.steps.size 
    @position = @position + 1 
    self.position = @position 
    end 
end 

路線:

resources :tutorials do 
    resources :steps 
end 

def show 
    @tutorial = Tutorial.find_by_permalink(params[:id]) 
    @steps = @tutorial.steps 
    @next = @steps[0] 
    @title = "#{@tutorial.name} - A Ruby on Rails tutorial" 
    respond_to do |format| 
    format.html # show.html.erb 
    format.xml { render :xml => @tutorial } 
    end 
end 

教程放映視圖

<%= render :partial => @tutorial.steps %> 

回答

3

你在哪裏設置的順序?你可以做這樣的:

@steps = @tutorial.steps.order('position') 

甚至更​​好,因爲我想不出任何情況下,你想出來的順序步驟:

在STEP模型:

default_scope order('position') 

或者,您可以在關聯定義定義的順序:

在教程模式:

has_many :steps, :order => 'position' 

編輯,只是爲它的地獄,這裏是一個更簡潔的方式來寫你的assign_position方法:

def assign_position 
    self.position = tutorial.steps.size + 1 
    end 
+0

感謝man_reworking assign_position方法在我的待辦事項列表中。 – RobertH

0

您的指定位置的邏輯是有缺陷的,如果步驟都可以任意添加和刪除。

例如

  • 我創建了一個教程和3個步驟,其中位置[1,2,3]。
  • 然後我刪除位置爲2的步驟。
  • 現在還剩下2個步驟[1,3]。
  • 後來我創建了另一個步驟,分配了位置3.
  • 現在有三個步驟,但它們的位置是[1,3,3]。那是不對的!

有幾個方法我會考慮改變這種狀況:

第一種方式

你可以把你的代碼分配位置,以一個新的臺階,但是當一個步驟中去除從教程中更新了職位,以確保他們是順序的。這是一個如何工作的草圖。

class Tutorial 
    def rectify_step_positions 
    # reassign positions so that all the steps form a sequence 
    # E.g. step positions [1,3,4] become [1,2,3] 
    end 
end 

class Step 
    after_destroy :trigger_rectify_positions 

    def trigger_rectify_positions 
    tutorial.rectify_step_positions 
    end 
end 

當你創建你可以指定爲比現有的所有步驟中的最大位置1越大,它的位置了新的一步方式二

def assign_position 
    self.position = tutorial.steps.order("position DESC").first.position + 1 
end 

該方法比第一種實現方法稍微簡單一些。當然,現在這些職位沒有太多的意義,因爲他們不一定是連續的。位置10的步驟可能是本教程的第二步。

結論

一旦你有固定的位置問題,那麼你可以簡單的順序執行這些步驟。布魯克已經顯示了幾種方法來做到這一點。我個人喜歡has_many :steps, :order => 'position'

+0

非常感謝。我會爲你的答案投票,但我的聲望不夠高。 – RobertH

+0

它是什麼has_many:steps,:order =>'id'。我認爲這是隱含的,但我猜不是。 – RobertH