Rails哈斯多关系:创建不保存记录到数据库?



如果我假设模型:

class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
end

当我试图运行User.first.posts.create [attributes],模型被创建,但它的id是nil,不保存在数据库中。有人能解释一下原因吗?我认为这种行为应该出现在#new中,而不是#create中。

你的期望是错误的。

如果验证通过,创建一个对象(或多个对象)并将其保存到数据库。无论对象是否成功保存到数据库,都会返回结果对象。

实现实际上非常简单:

def create(attributes = nil, &block)
if attributes.is_a?(Array)
attributes.collect { |attr| create(attr, &block) }
else
object = new(attributes, &block)
object.save
object
end
end

例如,当你这样做时:

post = Post.create(title: 'Not a valid post')

这将始终返回post的实例。如果你检查对象,你会发现它没有被持久化,errors对象会告诉你原因:

post.valid? # false
post.persisted? # false
post.errors.full_messages # ["User can't be blank."]

如果你创建了一个关联的记录,你也在改变它:

user = User.first
post = user.posts.create(attributes)
user.posts.to_a.include?(post) # true

这似乎是不希望看到的行为,但这是嵌套属性正常工作所必需的。

使用create!(如果记录无效则会引发错误)而不是在非交互式上下文中(如种子文件),其中创建记录不应该失败。不要在无效输入不是异常事件的情况下使用它,它只是一种拐杖,类似于抛出一堆日志或在代码中放置语句。编写覆盖无效和有效输入的测试。

如果你真的需要使用一个调试器,如byebugpry进入控制器的动作和检查模型实例。

最新更新