为什么rails没有在从create返回的项中填充一个自动递增的列?有没有更好的方法来做到这一点?
在Rails中,当执行a = Foo.create
时,将填充a.id
但是如果你有一个通过
def up
execute "ALTER TABLE my_table ADD COLUMN my_auto_incrementing_column INTEGER AUTO_INCREMENT not null UNIQUE KEY;"
end
那么当你使用创建时,那个字段就不会出现。你还必须使用重新加载。
a = Foo.create
a.id # not nil
a.my_auto_incrementing_column # nil
a.reload
a.my_auto_incrementing_column # is now populated
版本信息:
$ ruby -v
ruby 1.9.3p484 (2013-11-22 revision 43786) [x86_64-darwin14.5.0]
$ bundle exec rails -v
Rails 3.2.12
$ mysql --version
mysql Ver 14.14 Distrib 5.6.26, for osx10.10 (x86_64) using EditLine wrapper
一些背景:
这段代码被应用到一个现有的大型生产Rails代码库中,该代码库要求所有的id字段都是UUID。auto_increment列不是主键,因为它是在我们发现一个新的外部集成合作伙伴无法使用我们现有的长唯一标识符(UUID)处理之后添加的。
我们正在努力更新我们的ruby版本,但我们不想等待它作为这个问题的解决方案。而且,在阅读了activerecord中的changelogs之后,我仍然没有证据表明任何未来版本的ruby/rails将包含针对这个问题的bug修复。
我想改进的代码:
class Foo < ActiveRecord::Base
has_one :object_containing_auto_incrementing_column
def my_method
if self.object_containing_auto_incrementing_column.nil?
self.object_containing_auto_incrementing_column = ObjectContainingAutoIncrementingColumn.create(owner: self)
self.object_containing_auto_incrementing_column.reload
end
self.object_containing_auto_incrementing_column.my_auto_incrementing_column
end
end
2条答案
按热度按时间hts6caw31#
After looking at the source code it does not appear that ActiveRecord tries to populate auto-incrementing columns. It only assigns the value that is returned by the
INSERT
statement to the#id
attribute and nothing else.If you want to populate
my_auto_incrementing_column
without hitting the DB twice, I think there is no way around patching ActiveRecord itself.Have a look at how the insert method is implemented:
There might not be any trivial way to change the current API to populate your field in question.
ql3eal8s2#
显然,仍然不可能在create()中获取SEQUENCE在数据库级别自动增量中生成的字段(不是id)。
我解决了这个问题
在我例子中:PostgreSQL按序列自动增量
使用after_create回调