FactoryGirl 具有 Oracle 增强型适配器 - 名称“id”的属性;未分配
我有一个 Oracle 测试表,其 ID 列不是主键,不是自动增量,并且没有定义了序列。它只定义了NOT NULL
。开发模式中的相应结构是 Oracle 视图,而不是具有针对 ID 列定义的主键的表。
我的工厂定义如下:
FactoryGirl.define do
factory :model do
id 'abc'
end
end
这些测试失败
test "should build model 1" do
w = FactoryGirl.build(:model)
assert_not_nil w.id #fails - id is always nil
end
test "should build model 2" do
w = FactoryGirl.build(:model, :id => 'abc')
assert_not_nil w.id #fails - id is always nil
end
我已将 attr_accessible :id
添加到我的模型中(以防万一),但没有运气。
我还在我的模型中定义了 id=
方法 def id= id; @id = id;结束
。对方法进行了调用并写入了 @id,但看起来它稍后在调用堆栈中(FactoryGirl 和 ActiveRecord 之间)被覆盖。
通常分配其他属性。
I have an Oracle test table with ID column that is not a primary key, not an autoincrement and with no sequence defined. It only has NOT NULL
defined. The corresponding structure in development schema is an Oracle View rather than a table with a primary key defined against the ID column.
My factory definition looks like:
FactoryGirl.define do
factory :model do
id 'abc'
end
end
These tests fails
test "should build model 1" do
w = FactoryGirl.build(:model)
assert_not_nil w.id #fails - id is always nil
end
test "should build model 2" do
w = FactoryGirl.build(:model, :id => 'abc')
assert_not_nil w.id #fails - id is always nil
end
I've added attr_accessible :id
to my model (just in case), but with no luck.
I've also defined id=
method in my model def id= id; @id = id; end
. The call is made to the method and @id is written, but looks like it is overwritten later in the callstack (between FactoryGirl and ActiveRecord).
Other attributes are normally assigned.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我找到了罪魁祸首:
ActiveRecord::AttributeMethods::Write
模块中的write
方法有一行attr_name = self.class.primary_key if attr_name == 'id '
这意味着如果要设置的属性名称为“id”,则选择primary_key作为要为其分配新值的属性名称。由于在我的测试表中,oracle_enhanced_adapter 没有返回primary_key(正确地),因此跳过整个写入操作。
我的解决方案是覆盖
write
方法,跳过该行,以便写入 id。I found the culprit:
The
write
method inActiveRecord::AttributeMethods::Write
module has the lineattr_name = self.class.primary_key if attr_name == 'id'
It means that if the attribute name to be set has the name of 'id', pick the primary_key as the name of the attribute to assign the new value to. And since in my test table there is no primary_key returned by the oracle_enhanced_adapter (rightfully), the whole write operation is skipped.
My solution was to override the
write
method skipping that line so that the id is written to.如果显式设置主键怎么办?与 set_primary_key nil
只是一个想法;希望允许您不需要重写 write 方法。
What if you explicitly set the primary key? With set_primary_key nil
Just a thought; hopefully allows you to not need to override the write method.