Почему это где (). First_or_create генерирует неправильный SQL только в RSpec? - PullRequest
3 голосов
/ 24 марта 2012

Я наблюдаю случай, когда Action.where(:name => "fred").first_or_create генерирует неправильный SQL при запуске под RSpec, но работает правильно в консоли.Я сбит с толку.

Вот модель.Базовая таблица 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 генерирует SQL

SELECT "actions".* FROM "actions" WHERE "name"."name" = 'fred' LIMIT 1

... что не так - он ищет таблицу с именем "name".

Странно то, что ввод в консоли одинаковых вещей выполняется правильно.И да, я запомнил (на этот раз), чтобы набрать rake db:test:prepare перед выполнением моих тестов RSpec.Я бегу

Ruby version              1.9.3 (x86_64-darwin10.8.0)
Rails version             3.2.1
RSpec                     2.9.0

Какого черта здесь происходит?

1 Ответ

1 голос
/ 24 марта 2012

Action.internalize(:name => "fred") создает предложение where:

where(:name => {:name => "fred"})

, означающее, что вы связали таблицу name, которая имеет столбец name со значением fred

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...