#ruby-on-rails #postgresql #rspec
#ruby-on-rails #postgresql #rspec
Вопрос:
У меня возникла проблема с тем, что Rails не вводит значения в postgresql. Подключена сама база данных. Когда я запускаю db:create:all (фрагмент из database.yml)
development:
adapter: postgresql
encoding: unicode
database: website_development
username: postgres
password: *******
host: 127.0.0.1
port: 9435
(тест: то же самое, но с database: website_test вместо website_development) все базы данных созданы для тестирования и разработки. Когда я запускаю свою db: миграция, также создается таблица пользователя, например, фрагмент из файла миграции «date»_create_user.rb
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :username
t.string :email
t.timestamps
end
end
def self.down
drop_table :users
end
end
(Я проверил в pgAdmin и нашел таблицы, которые были созданы), Но когда я пытаюсь вставить данные с консоли, например (это было запущено в изолированной среде)
irb(main):001:0> User.create!(:username => "John", :email => "john@example.com)
=> #<User id: 1, username: nil, email: nil, created_at: "2011-04-26 22:00:28", u
pdated_at: "2011-04-26 22:00:28">
вот sql, созданный при другом create! Я запустил
[1m[35mSQL (2.0ms)[0m INSERT INTO "users" ("username", "email", "created_at", "updated_at") VALUES (NULL, NULL, '2011-04-26 20:53:43.363908', '2011-04-26 20:53:43.363908') RETURNING "id"
Любая помощь относительно того, почему rails создает базы данных и таблицы нормально, но не может найти правильное имя пользователя и адрес электронной почты для ввода в sql.
P.S. Я запускаю Rspec для своих тестов и провел несколько тестов на предмет того, что значения username и email не равны нулю, и все они успешны.
......................
Finished in 1.62 seconds
22 examples, 0 failures
Notification failed: 201 - The destination server was not reachable
Notification failed: 201 - The destination server was not reachable
Как вы можете видеть, все тесты Rspec имеют зеленый цвет, но у него возникают проблемы с подключением к серверу postgres
Заранее благодарю вас за любой совет.
Обновление: добавлен фрагмент модели пользователя
class User < ActiveRecord::Base
attr_accessor :username, :email
email_regex = /A[w -.] @[a-zd-.] .[a-z] z/i
username_regex = /A[wd] z/i
validates :username, :presence => true,
:format => { :with => username_regex },
:length => { :maximum => 30},
:uniqueness => { :case_sensitive => false }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false }
end
==Ответ==
Это были мои ошибки:
Часть 1: Изменив attr_accessor
на attr_accessible
, чтобы все мои тесты работали должным образом, и все, что нужно, было выделено красным, это также позволило мне добавить :email
детали, но не :username
детали, которые ведут к части 2.
Часть 2: По какой-то причине rails не понравилось, что моя таблица была названа :user
и мой столбец был назван :username
. Итак, я попытался изменить:username на :loginname
, что полностью устранило проблему.
Спасибо всем за вашу помощь.
Комментарии:
1. пожалуйста, опубликуйте свой пользовательский класс. Выглядит как активная запись
2. также проверьте pg_hba.conf, чтобы узнать, разрешает ли pg подключения от определенного пользователя извне через имя / pw login
Ответ №1:
Чтобы изолировать это, вы можете создать модульный тест для репликации проблемы, а затем исправить его по мере необходимости. Сначала я подозревал, что это будет случай защищенных атрибутов, но, похоже, вы сделали их доступными, что является правильным решением.
Вызов create!
напрямую несколько опасен, поскольку вы не сможете легко захватить объект, который наполовину создан, в случае исключения. Это потому, что, хотя исключение содержит ссылку на модель, неясно, пользовательская модель или какая-либо другая модель вызвала исключение в первую очередь без дополнительного копания.
Более надежный подход заключается в следующем:
def test_create_example
user = User.new(:username => "John", :email => "john@example.com")
assert_equal 'John', user.username
assert_equal 'john@example.com', email
user.save
assert_equal [ ], user.errors.full_messages
assert_equal false, user.new_record?
end
Если в потоке проверки возникает ошибка, вы увидите ошибку, указанную рядом с тем, что должно быть пустым массивом. Он также проверяет, была ли сохранена запись, проверяя, что это больше не новая запись, поскольку записи могут быть действительными, но не сохранятся, если before_save
или before_create
фильтр возвращает false
, что происходит случайно довольно часто.
Если вы вызываете new
и затем save
, у вас есть возможность проверить только что подготовленный объект до его сохранения, а также после.
Комментарии:
1. Я попытался запустить команду ‘user = User.new’. В результате все значения равны null, и если выполняется ‘user.save’, который каким-то образом принимает значение true, то я получаю тот же результат, как если бы я использовал ‘create!’. Какой идентификатор (увеличенный), имя пользователя (ноль), адрес электронной почты (ноль), created_at (созданный), updated_at (созданный)
2. Тогда у вас возникла проблема с присвоением ваших атрибутов, что указывает на то, что что-то защищает их в модели. Если это вся ваша пользовательская модель, она должна работать нормально, но, возможно, у вас есть надстройка, подобная Devise, которая изменяет ее извне.
3. Кроме аннотации, которая является всей моей пользовательской моделью. Я не запускаю никаких дополнений для аутентификации, таких как Devise, в этом проекте. Единственными камнями, которые я использую, являются annotaion (для разработки), rspec и webrat (для тестов).
4. Я попробовал db: rollback, но это не привело к удалению таблиц из psql, поэтому я вручную удалил их и снова запустил миграцию. Миграция сработала и снова создала таблицы, но у меня все еще та же проблема. Также тот факт, что
User.new
иUser.create!
не удается создать имя пользователя и адрес электронной почты перед тем, как попасть в базу данных, заставляет меня думать, что это не проблема postgres.5. Вы могли бы попробовать протестировать движок sqlite по умолчанию, чтобы посмотреть, не мешает ли это, или создать другую модель с теми же внутренними компонентами, но с другим именем и удалять фрагменты, пока не сможете заставить ее работать. Похоже, вам нужно сузить проблему здесь, если другие модели работают должным образом.