我是很新,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_tags
和all_super_tags
產生遞歸陣列)
它的工作原理,但我真的不喜歡這樣的解決方案:至少,它的用戶,他應該使用..._copy
方法並不明顯。
也許我這樣做不對嗎?
UPD:
或者是不好的做法,一般不允許用戶更改錯誤方法的對象?大概我應該允許用戶以錯誤的方式改變一個對象,但只有在保存之前驗證它?
至少,我已經想通了,這是很難,如果用戶做錯了事提供錯誤信息:目前,模型只是默默不修改一個對象,並且不產生錯誤消息。我必須實現我自己的錯誤消息引擎,這個事實證明這種方法非常糟糕......我似乎在與框架而不是使用它的鬥爭中掙扎。