快速提问has_many
和belongs to
。我处于:user has_many :accounts
和:account belongs_to the user
。
在我的控制器中,我首先指定@accounts = current_user.accounts
。调试[正确]向我报告此特定用途有2个帐户。在下一行中,我保存了一个无效帐户(调试也正确地告诉我它是无效的)。但是,当我检查current_user.accounts.count
与current_user.accounts.all.count
与current_user.accounts.all(order: 'created_at DESC')
时,我会得到以下值:
- current_user.accounts.count = 2
- current_user.accounts.all.count = 3
- current_user.accounts.all(order: 'created_at DESC') = 2
检查数据库确认无效模型确实没有保存。
此外,在我的动态ajax重新加载的视图中,我提供@accounts = current_user.accounts
(在if-else循环检查if @account.save
工作之后设置),它循环显示3个帐户,包括无效的帐户。
这是控制器的代码:
def create
@account = current_user.accounts.new(account_params)
if @account.save
@accounts = current_user.accounts.all(order: 'created_at DESC')
#redirect_to accounts_path, :success => "Account successfully created."
flash[:success] = "Account sucessfully created."
# respond_to :js
respond_to do |format|
format.js {
render :create
}
end
else
@accounts = current_user.accounts.all(order: 'created_at DESC')
flash[:error] = "There was a problem with adding your account."
respond_to do |format|
format.js {
render :create
}
end
end
puts "Final Accounts is #{@accounts.count} compared to #{current_user.accounts.all.count} compared to #{current_user.accounts.count}" # outputs 2, 3, and 2 for an invalid model being saved
end
有人可以向我解释我应该这样做的正确方法吗?或者更好的是,Rails引擎下发生了什么?有这个问题,我觉得羞怯的菜鸟。
如何告诉rails只加载保存在db中的current_user.accounts
?这种热切加载是否相关?
我正在使用postgresql在Rails 4上运行,如果这有所不同。
答案 0 :(得分:2)
ActiveRecord::Associations
中混淆的原因是CollectionProxy (事情比他们看起来要复杂得多):
current_user.accounts
是CollectionProxy,而不是Array
。
将CollectionProxy视为容器,内部具有@owner
作为current_user,@target
作为帐户集和@reflection
- @owner
和{之间的链接(关联) {1}}
当您运行@target
时 - 您只需将另一个对象添加到current_user.accounts.new()
中,因此迭代@target
您将在@target上进行迭代,其中包含包含新创建的对象。
但是等等,为什么current_user.accounts
会返回更少的对象?
因为Rails是惰性的,所以在你真正需要它的对象(= accounts)之前不会加载.count
。因此,只运行@target
运行直接SQL请求,而不是.count
中所有对象的实例化,然后计算'em。
这就是为什么当你@target
获得保存对象的数量时。当您执行current_user.accounts.count
时,它会实例化current_user.accounts.all.count
中的所有对象,将'转换为@target
并计算此数组中的帐户(等于Array
)。
顺便说一下,在Rails 4中不推荐使用current_user.accounts.size
,而是使用all
那么,我对所有这些知识做了什么,伙计?我只需要显示没有未保存帐户的帐户。
强制重新加载:to_a
或@accounts = current_user.accounts(force_reload = true)
OR @accounts = current_user.accounts.reload
它将自动运行重载,因为订单需要通过SQL直接请求对象