簡體   English   中英

Rails 4-鏈接模型關聯以訪問關聯的方法

[英]Rails 4 - chaining model associations to access associated methods

我有用於用戶,個人資料和組織請求的模型。 關聯是:

用戶

has_one :profile, dependent: :destroy
has_one :organisation_request, through: :profile 
    accepts_nested_attributes_for :organisation_request

輪廓

belongs_to :user
belongs_to :organisation

組織要求

belongs_to :profile
# belongs_to :user#, through: :profile  
belongs_to :organisation

在我的用戶模型中,我有一個名為full_name的方法(用於格式化用戶名的表示形式。

我正在嘗試在organisation_requests模型中訪問該full_name方法。

我正在嘗試通過在組織的請求模型中編寫以下方法來做到這一點:

def related_user_name
    self.profile.user.full_name
end

當我嘗試在我的組織請求索引中使用它時,如下所示:

          <%= link_to orgReq.related_user_name, organisation_request.profile_path(organisation_request.profile.id) %>

我收到一條錯誤消息:

undefined method `user' for nil:NilClass

當我嘗試在rails控制台中使用此想法時,請執行以下操作:

o = OrganisationRequest.last

  OrganisationRequest Load (0.4ms)  SELECT  "organisation_requests".* FROM "organisation_requests"  ORDER BY "organisation_requests"."id" DESC LIMIT 1
 => #<OrganisationRequest id: 2, profile_id: 1, organisation_id: 1, created_at: "2016-08-01 22:48:52", updated_at: "2016-08-01 22:48:52"> 
2.3.0p0 :016 > o.profile.user.formal_name
  Profile Load (0.5ms)  SELECT  "profiles".* FROM "profiles" WHERE "profiles"."id" = $1 LIMIT 1  [["id", 1]]
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1  [["id", 1]]
 => " John Test" 

該概念似乎可以在控制台中使用? 誰能看到我哪里出問題了?

不要鏈接方法,這是一種不好的做法,它違反了Demeter定律 最好的選擇是使用delegate 所以代替:

def related_user_name
  self.profile.user.full_name
end

你可以有:

class OrganisationRequest
  belongs_to :profile
  has_one :user, through: :profile

  delegate :full_name, to: :user, allow_nil: true, prefix: true
end

然后,您可以只調用organisation_request.user_full_name ,它將通過配置文件>用戶並調用full_name (並且您將不會得到undefined因為allow_nil: true會“覆蓋”它)

有關委托的更多信息,請點擊這里

您是否檢查了所有組織請求的個人資料? 可能不是最佳做法,請嘗試使用profile.try(:user).try(:full_name)

暫無
暫無

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

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