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。就目前情況而言,我沒有看到它提到多個協會。
同意。這是一個荒謬的方法名稱。我只是很難找出如何更好地做到這一點。 – Neil