我看到一种情况,其中Action.where(:name => "fred").first_or_create
在RSpec下运行时生成不正确的SQL,但在控制台中正确执行。我很困惑。
这是模型。基础actions
表具有一个字段,一个名为name
的字符串:
# file: app/models/action.rb
class Action < ActiveRecord::Base
def self.internalize(name)
self.where(:name => name).first_or_create
end
end
这是rspec测试:
# file: spec/models/action_spec.rb
require 'spec_helper'
describe Action do
describe 'intern' do
it 'should create a new name' do # works
lambda { Action.internalize("fred") }.should change { Action.count }.by(1)
end
it 'should not create duplicate names' do # fails
Action.internalize(:name => "fred")
lambda { Action.internalize("fred") }.should_not change { Action.count }
end
end
end
这是失败的地方:
1) Action intern should not create duplicate names
Failure/Error: Action.internalize(:name => "fred")
ActiveRecord::StatementInvalid:
PG::Error: ERROR: missing FROM-clause entry for table "name"
LINE 1: SELECT "actions".* FROM "actions" WHERE "name"."name" = 'f...
: SELECT "actions".* FROM "actions" WHERE "name"."name" = 'fred' LIMIT 1
# ./app/models/action.rb:4:in `internalize'
# ./spec/models/action_spec.rb:12:in `block (3 levels) in <top (required)>'
似乎当记录存在时,
Action.where(:name => "fred").first_or_create
正在生成SQLSELECT "actions".* FROM "actions" WHERE "name"."name" = 'fred' LIMIT 1
...这是错误的-它正在寻找一个名为“ name”的表。
奇怪的是,在控制台中键入完全相同的内容会正常执行。是的,我记得(这次)在运行RSpec测试之前键入
rake db:test:prepare
。我在跑Ruby version 1.9.3 (x86_64-darwin10.8.0)
Rails version 3.2.1
RSpec 2.9.0
这里到底发生了什么?
最佳答案
Action.internalize(:name => "fred")
正在生成where子句:
where(:name => {:name => "fred"})
这意味着,您有一个关联的表
name
,该表的列name
的值为fred
关于ruby-on-rails - 为什么where()。first_or_create仅在RSpec中生成不正确的SQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9846567/