Rails Active Record:在调用Save方法之前,调用构建方法不应保存到数据库

dmi*_*ion 4 ruby activerecord ruby-on-rails-3

我有一个简单的用户模型

class User < ActiveRecord::Base
    has_one :user_profile
end
Run Code Online (Sandbox Code Playgroud)

还有一个简单的user_profile模型

class UserProfile < ActiveRecord::Base
    belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)

问题是,当我调用以下构建方法而不调用save方法时,我最终得到了数据库中的新记录(如果它通过了验证)

class UserProfilesController < ApplicationController

def create
        @current_user = login_from_session
        @user_profile = current_user.build_user_profile(params[:user_profile])
       #@user_profile.save (even with this line commented out, it still save a new  db record)
        redirect_to new_user_profile_path

end
Run Code Online (Sandbox Code Playgroud)

Anyyyyyy有任何想法正在发生什么.

这种方法的定义如下所示,但它仍然为我节省

build_association(attributes = {})

    Returns a new object of the associated type that has been instantiated with attributes and linked to this object through a foreign key, but has not yet been saved.
Run Code Online (Sandbox Code Playgroud)

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_one

dmi*_*ion 8

好吧,我确信经验丰富的兽医已经知道了这一点,但作为一个新手,我不得不弄清楚这一点......让我看看我是否可以解释这个而不搞砸了

虽然我没有直接保存user_profile对象,但我在日志中注意到每次提交表单时都会更新用户模型的last_activity_time(以及user_profile模型)(当登录用户执行时,用户模型的last_activity日期也会更新)各种其他事情 - 我后来意识到这是在Sorcery宝石配置中设置的).

根据http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html.AutosaveAssociation 是一个模块,负责在保存父项时自动保存相关记录.在我的例子中,用户模式是父级,他们提供的场景反映了我的经验.

class Post
  has_one :author, :autosave => true
end 

post = Post.find(1)
post.title       # => "The current global position of migrating ducks"
post.author.name # => "alloy"

post.title = "On the migration of ducks"
post.author.name = "Eloy Duran"

post.save
post.reload
post.title       # => "On the migration of ducks"
post.author.name # => "Eloy Duran"
Run Code Online (Sandbox Code Playgroud)

以下解决方案解决了我的问题1.停止Sorcery(配置设置)更新用户last_activity_time(对于每个操作)或2.当我在用户模型中设置关联时,传递':autosave => false'选项如下

class User < ActiveRecord::Base
    has_one :user_profile, :autosave => false
end
Run Code Online (Sandbox Code Playgroud)