簡體   English   中英

具有多個關聯的Rails委托方法

[英]Rails delegate method with more than one association

delegate方法似乎是在Rails應用程序中各處進行nil檢查的絕佳替代方法,但是我在將其應用於多個關聯的情況時遇到了麻煩。

考慮以下關聯:

#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 ,因此,如果我對此user執行以下操作,則以下代碼將破壞應用程序:

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

所以我可以這樣做:

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

但這是一個nil檢查,我們要避免nil檢查,因為否則它們將絕對存在於應用程序中的任何地方。

因此,您可以執行以下操作,以應用得墨meter耳定律,並且效果很好:

# 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

很好,可以,我們避免了nil檢查。 但是,如果我們想獲取關聯的hash_tag.tag_name怎么hash_tag.tag_name 如果nil不是問題,我們可以這樣做:

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

這不僅會破壞demeter的定律,而且因為nil 一個問題並且關聯的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文檔 我沒有看到像我目前的情況那樣提及多個協會。

個人觀點, @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

我建議您使用Null Object Pattern ,它在https://github.com/avdi/naught gem(檢查其文檔,很糟糕!)及其ActiveRecord對應的https://github.com/Originate中很好地實現了/ active_null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM