在我的应用中,用户belongs_to
是客户,客户是has_many
construction_sites
。因此,当我想仅显示current_user
construction_sites
时,我有多种可能性,其中没有一种是优雅的:
@construction_sites = ConstructionSite.where(customer: current_user.customer)
除了用户尚未与客户关联的情况外,这种方法效果很好。然后,我收到PG::UndefinedColumn: ERROR: column construction_sites.customer does not exist
错误。
@construction_sites = ConstructionSite.where(customer_id: current_user.customer_id)
这似乎在第一眼就能正常工作,但对于用户尚未与客户current_user.customer_id
关联的情况,nil
和ConstructionSite.where(customer_id: nil)
会被调用,这会选择所有(或者所有未分配的网站,这不是我想要的。
unless...
unless current_user.customer.nil?
@construction_sites = ConstructionSite.where(customer: current_user.customer)
else
@construction_sites = []
end
这很有效,但看起来不太好。
ConstructionSite.joins(customer: :users).where('users.id' => current_user.id)
有效,但看起来不太好。
那么,这个问题最优雅的解决方案是什么?
答案 0 :(得分:2)
尝试使用delegate关键字。将其添加到您的用户模型。
delegate :construction_sites, to: :customer, allow_nil: true
之后您可以使用
之类的语句current_user.construction_sites
我发现所有选项中最优雅的。
答案 1 :(得分:0)
def user_construction_sites
@construction_sites = []
@construction_sites = current_user.customer.construction_sites if current_user.customer.present?
@construction_sites
end
答案 2 :(得分:0)
如何将逻辑移动到命名范围并插入保护条款?
class SomeController < ApplicationController
def some_action
@construction_sites = ConstructionSite.for(current_user)
end
end
class ConstructionSite < ActiveRecord::Base
def self.for(user)
return [] if user.customer.blank?
where(customer: user.customer)
end
end