简体   繁体   English

Rails 4-链接模型关联以访问关联的方法

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

I have models for User, Profile and Organisation Request. 我有用于用户,个人资料和组织请求的模型。 The associations are: 关联是:

User 用户

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

Profile 轮廓

belongs_to :user
belongs_to :organisation

Organisation Request 组织要求

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

In my user model, I have a method called full_name (which I use to format the presentation of a user's name. 在我的用户模型中,我有一个名为full_name的方法(用于格式化用户名的表示形式。

I'm trying to access that full_name method in my organisation_requests model. 我正在尝试在organisation_requests模型中访问该full_name方法。

I'm trying to do that by writing the following method in my organisation requests model: 我正在尝试通过在组织的请求模型中编写以下方法来做到这一点:

def related_user_name
    self.profile.user.full_name
end

When I try to use this in my organisation requests index, like this: 当我尝试在我的组织请求索引中使用它时,如下所示:

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

I get an error that says: 我收到一条错误消息:

undefined method `user' for nil:NilClass

When I try to use this idea in the rails console, with: 当我尝试在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" 

The concept seems to work in the console? 该概念似乎可以在控制台中使用? Can anyone see where I've gone wrong? 谁能看到我哪里出问题了?

Don't chain methods, it's a bad practice, it violates the Law of Demeter . 不要链接方法,这是一种不好的做法,它违反了Demeter定律 The best choice is to use the delegate . 最好的选择是使用delegate So instead of: 所以代替:

def related_user_name
  self.profile.user.full_name
end

You can have: 你可以有:

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

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

Then you can just call organisation_request.user_full_name and it will go through profile > user and call full_name (and you won't get undefined since the allow_nil: true will "cover" it) 然后,您可以只调用organisation_request.user_full_name ,它将通过配置文件>用户并调用full_name (并且您将不会得到undefined因为allow_nil: true会“覆盖”它)

More info about delegate here . 有关委托的更多信息,请点击这里

have you checked all of your organisation requests have profile? 您是否检查了所有组织请求的个人资料? may be this is not best practice, try to use profile.try(:user).try(:full_name) 可能不是最佳做法,请尝试使用profile.try(:user).try(:full_name)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM