2013-12-21 47 views
3

我是很新,Ruby和Ruby-上軌,所以我需要學習的最佳做法。導軌:聯想的has_many:最佳實踐來驗證訪問陣列

我有Tag模型中,每個標籤可以有許多子標籤和許多超級標籤:

has_many :super_tags, :through => :tag_hier_rels,   :source => :super_tag 
    has_many :sub_tags, :through => :reverse_tag_hier_rels, :source => :sub_tag 

    has_many :tag_hier_rels,   :foreign_key => "sub_tag_id" 
    has_many :reverse_tag_hier_rels, :foreign_key => "super_tag_id", :class_name => "TagHierRel" 

我需要防止用戶創建循環引用。但與自動生成的方法:super_tags:sub_tags我不能這樣做:每個人都可以做這樣的事情:

tag.super_tags.push another_tag,我無法控制這一點。 Rails的驗證機制在這裏是沒有用的:這種機制可以防止用戶保存無效對象數據庫,但我要阻止他,甚至錯誤地修改對象:如果我有循環引用,我需要得到所有的子標籤或超級標籤遞歸,我會遇到堆棧溢出。

所以我也做了以下內容:

聲明這些協會爲私有的:

private :sub_tags=, :sub_tags 
private :super_tags=, :super_tags 

添加的方法與_copy後綴:

def sub_tags_copy 
    return sub_tags.clone 
end 

def super_tags_copy 
    return super_tags.clone 
end 

而添加的方法是actualy修改陣列:

def sub_tags_push(tag) 
    sub_tags.push tag if !self.all_sub_tags.include? tag and !self.all_super_tags.include? tag 
    end 

    def super_tags_push(tag) 
    super_tags.push tag if !self.all_sub_tags.include? tag and !self.all_super_tags.include? tag 
    end 

    # TODO: more methods (at least we need to remove tags) 

(方法all_sub_tagsall_super_tags產生遞歸陣列)

它的工作原理,但我真的不喜歡這樣的解決方案:至少,它的用戶,他應該使用..._copy方法並不明顯。

也許我這樣做不對嗎?

UPD:

或者是不好的做法,一般不允許用戶更改錯誤方法的對象?大概我應該允許用戶以錯誤的方式改變一個對象,但只有在保存之前驗證它?

至少,我已經想通了,這是很難,如果用戶做錯了事提供錯誤信息:目前,模型只是默默不修改一個對象,並且不產生錯誤消息。我必須實現我自己的錯誤消息引擎,這個事實證明這種方法非常糟糕......我似乎在與框架而不是使用它的鬥爭中掙扎。

回答

0

你總是提到user,你的意思是programmers

如果是這樣的話,你應該嘗試通過

  1. 教育(開發者開發)
  2. 驗證斷言這種東西(通過測試或滑軌驗證)
  3. 約束(上數據庫級別通過數據庫約束或觸發器)

我會盡量自上而下。