2015-10-06 41 views
0

delegate方法似乎是在rails應用程序中遍佈整個場所進行零檢查的一個很好的選擇,但是我無法將其應用於有多個關聯的情況。帶有多個關聯的Rails委託方法

考慮這些協會:

#app/models/user.rb 
class User < ActiveRecord::Base 
    belongs_to :blog 
end 

#app/models/blog.rb 
class Blog < ActiveRecord::Base 
    belongs_to :hash_tag 
    has_one :user 
end 

#app/models/hash_tag.rb 
class HashTag < ActiveRecord::Base 
    has_one :blog 
end 

我搶用戶:

@user = User.find(1) 

而且我想找到他的博客:

@user.blog 
    => nil 

它返回nil這裏,因爲這user情況沒有關聯blog,所以下面的代碼會打破t他的應用程序,如果我做了這樣的事情本user

@user.blog.title 
    => undefined method `title' for nil:NilClass 

所以我能做到這一點:

@user.blog.title if @user.blog.present? 

但是,這是一個零檢查,我們要避免零檢查,因爲否則會絕對無處不在的應用程序。

這樣你就可以做到這一點,其適用迪米特法則偉大工程:

# open up app/models/user.rb 
class User < ActiveRecord::Base 
    belongs_to :blog 
    delegate :title, to: :blog, prefix: true, allow_nil: true #add this 
end 

現在我們可以做到這一點,這是偉大的,因爲如果user沒有blog則剛剛返回nil相對於該錯誤:undefined method 'title' for nil:NilClass

@user = User.find(1) 
@user.blog_title 

大,的作品,我們避免了零檢查。但是,如果我們想要獲取關聯的hash_tag.tag_name呢?如果無不是一個問題,我們可以這樣做:

@user = User.find(1) 
@user.blog_title.hash_tag.tag_name 

這不僅打破迪米特法則,但由於零的問題和相關的HASH_TAG對象可能不存在,我們再會有一天遇到錯誤:undefined method 'title' for nil:NilClass

我試圖再次打開該User類,並添加在一個委託一個嵌套的目標,但它不是爲我工作:

# again: open up app/models/user.rb 
class User < ActiveRecord::Base 
    belongs_to :blog 
    delegate :title, to: :blog, prefix: true, allow_nil: true 
    delegate :tag_name, to: :'blog.hash_tag', prefix: true, allow_nil: true #doesn't work 
end 

顯然,我的語法是關閉的,因爲它不喜歡我的指定這個嵌套目標爲::'blog.hash_tag'

我想要做的就是能夠說:@user.blog_hash_tag_tag_name。這可能與代表?

我確實評論了Delegate documentation。就目前情況而言,我沒有看到它提到多個協會。

回答

3

作爲個人觀點,@user.blog_hash_tag_tag_name是可怕的看看。

也就是說,想要在用戶級別定義兩個代表也是對LoD的違反,因爲您正在使用來自用戶類的博客內部工作知識(它屬於hash_tag)。

如果你想使用的代表,您應該添加到User

delegate :hash_tag_tag_name, to: :blog, prefix: true, allow_nil: true 

和類Blog

delegate :tag_name, to: :hash_tag, prefix: true, allow_nil: true 
+0

同意。這是一個荒謬的方法名稱。我只是很難找出如何更好地做到這一點。 – Neil