Rails在没有保存时​​有很多关系(可能是ajax相关的)

时间:2013-10-23 04:31:02

标签: ruby-on-rails ajax activerecord has-many eager-loading

快速提问has_manybelongs to。我处于:user has_many :accounts:account belongs_to the user

的情况

在我的控制器中,我首先指定@accounts = current_user.accounts。调试[正确]向我报告此特定用途有2个帐户。在下一行中,我保存了一个无效帐户(调试也正确地告诉我它是无效的)。但是,当我检查current_user.accounts.countcurrent_user.accounts.all.countcurrent_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上运行,如果这有所不同。

1 个答案:

答案 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直接请求对象