假设我有一个用户模型
user.rb
class User < ActiveRecord::Base
...
end
具有以下属性:名称,用户名,访问权限
access是一个枚举,告诉我用户是“员工”还是“客户”
要获取登录用户的名称和用户名,我可以这样做:
current_user.name
current_user.username
假设我有一个职员模型
staff.rb
class Staff < ActiveRecord::Base
belongs_to :user
end
具有以下属性:salary,phone_number
我也有一个客户模型
customer.rb
class Customer < ActiveRecord::Base
belongs_to :user
end
具有以下属性:address,phone_number
我希望能够在我的员工的控制器上打电话:
current_user.staff.salary
这是我客户的控制器:
current_user.customer.address
我追求的是什么
我覆盖了sessions_controller.rb
def create
super
model_name = current_user.access.capitalize.constantize
spec = model_name.where(user_id: current_user.id).take
session[:spec] = spec
end
所以我可以通过session [:spec]访问它,但不能通过current_user访问它。有什么想法吗?
答案 0 :(得分:1)
首先,您的用户模型应该引用员工或客户,即使他们要保持空白
class User
has_one :staff
has_one :address
通过这样做,您应该可以使用current_user.customer.address
。然而...
我建议你在ApplicationController或你包含的模块中添加一些方便的方法
def staff_signed_in?
@staff_signed_in ||= (user_signed_in? and current_user.access == :staff)
end
def current_staff
@current_staff ||= (current_user.staff if staff_logged_in?)
end
# same for customer
# Note that I use instance variables so any database queries are executed only once !
然后你可以简单地调用
<% if customer_signed_in? %>
<h2>Logged in as customer</h2>
<p>Address : <%= current_customer.address %>
<% end %>
编辑:关于您对数据库命中的担忧
您提供了current_user.customer.cart.products
的示例这确实是一个非常嵌套的关联。我上面的建议已经将它降低了一级(即current_customer == current_user.customer)。然后你必须经过推车才能到达产品......在我看来,它并不是那么糟糕。 如果你需要经常调用(current_customercustomer.cart),你可以覆盖给定控制器的current_customer并急切加载你将使用的资源。
def UserShopController < ApplicationController
# Let's assume current_customer is defined in ApplicationController like I showed above
# UserShopController always uses the customer cart, so let's load it right at the beginning
...
private
# Override with eager loading
def current_customer
@current_customer ||= (current_user.customer.includes(:cart) if customer_logged_in?)
end
答案 1 :(得分:1)
将has_one :customer
添加到您的user.rb
您的用户模型应如下所示访问相关模型。
class User < ActiveRecord::Base
has_one :customer
end