在为具有* _to_many关系的模型编写测试时遇到问题

时间:2014-06-13 20:04:55

标签: ruby sqlite minitest sequel

我有这些模特:

Sequel::Model.plugin(:schema)

DB = ENV['RUBY_ENV'].eql?('test') ? Sequel.sqlite('test.db') : Sequel.sqlite('database.db')
DB.loggers << Logger.new($stdout)

unless DB.table_exists?(:channel)
  DB.create_table :channel do
    string      :id, :unique => true, :primary_key => true
    string      :title, :null => false
    text        :description
    integer     :likeCount, :default => 0
  end
end

class Channel < Sequel::Model(:channel)
  unrestrict_primary_key
  one_to_many :videos
end

unless DB.table_exists? :video
  DB.create_table :video do
    string      :id, :primary_key => true
    string      :title, :null => false
    foreign_key :channel_id, :channel
    text        :description
    DateTime    :publishedAt
    DateTime    :updatedAt
    string      :category
    integer     :viewCount
    integer     :likeCount
    integer     :favoriteCount
    integer     :dislikeCount
  end
end

class Video < Sequel::Model(:video)
  unrestrict_primary_key
  many_to_one :channel
  many_to_many :comments
end

unless DB.table_exists? (:user)
  DB.create_table :user do
    primary_key :id
    string      :username
  end
end

class User < Sequel::Model(:user)
  unrestrict_primary_key
  one_to_many :comments
end

unless DB.table_exists? :comment
  DB.create_table :comment do
    primary_key :id
    foreign_key :user_id, :user
    foreign_key :video_id, :videos
    integer     :likeCount, :default => 0
  end
end

class Comment < Sequel::Model(:comment)
  many_to_one :user
  many_to_many :videos
end

涵盖他们的规格:

class TestChannel < SequelTestCase

  def test_that_id_can_be_provided
    Channel.create(id: 'testId1', title: 'testTitle')
    Channel.where(title: 'testTitle').count.must_equal 1
  end

  def test_title_cant_be_null
    -> {Channel.create(id:'testId2')}.must_raise Sequel::NotNullConstraintViolation
  end

  def test_default_likeCount_and_descrition
    Channel.create(id:'testId1', title:'testTitle', description: 'test')
    rec = Channel.first(title:'testTitle')
    rec.likeCount.must_equal 0
    rec.description.must_equal 'test'
  end
end

class TestVideo < SequelTestCase
  def test_provide_id

    Video.create(id:'testId', title:'testTitle')
  end
end

class TestUser < SequelTestCase
  def test_username
    User.create(username:'testName')
    User.first.username.must_equal 'testName'
  end
end

class TestComments < SequelTestCase
  def test_comments
    Comment.create
    Comment.first.likeCount.must_equal 0
  end
end

我推出了所有交易:

class SequelTestCase < MiniTest::Test
  def run(*args, &block)
    Sequel::Model.db.transaction(:rollback=>:always){super}
    self
  end
end

对于没有任何* _to_many关系的模特,一切都完美无瑕。但是对于任何* _to_many关系,我都会遇到这个错误:

TestComments#test_comments:
Sequel::DatabaseError: SQLite3::SQLException: no such table: main.videos

以下是来自SQLite的日志(我不明白为什么它引用main.videos表;它应该只是videos表):

I, [2014-06-14T02:51:44.856546 #79819]  INFO -- : (0.000055s) BEGIN
E, [2014-06-14T02:51:44.857538 #79819] ERROR -- : SQLite3::SQLException: no such table: main.channels: INSERT INTO `video` (`id`, `title`) VALUES ('testId', 'testTitle')
I, [2014-06-14T02:51:44.857870 #79819]  INFO -- : (0.000028s) ROLLBACK
I, [2014-06-14T02:51:44.858899 #79819]  INFO -- : (0.000023s) BEGIN
I, [2014-06-14T02:51:44.859825 #79819]  INFO -- : (0.000320s) INSERT INTO `channel` (`id`, `title`) VALUES ('testId1', 'testTitle')
I, [2014-06-14T02:51:44.860286 #79819]  INFO -- : (0.000152s) SELECT * FROM `channel` WHERE (`id` = 'testId1') LIMIT 1
I, [2014-06-14T02:51:44.860760 #79819]  INFO -- : (0.000073s) SELECT count(*) AS 'count' FROM `channel` WHERE (`title` = 'testTitle') LIMIT 1
I, [2014-06-14T02:51:45.168971 #79819]  INFO -- : (0.308073s) ROLLBACK
I, [2014-06-14T02:51:45.169546 #79819]  INFO -- : (0.000062s) BEGIN
I, [2014-06-14T02:51:45.170778 #79819]  INFO -- : (0.000524s) INSERT INTO `channel` (`id`, `title`, `description`) VALUES ('testId1', 'testTitle', 'test')
I, [2014-06-14T02:51:45.172969 #79819]  INFO -- : (0.000633s) SELECT * FROM `channel` WHERE (`id` = 'testId1') LIMIT 1
I, [2014-06-14T02:51:45.173788 #79819]  INFO -- : (0.000191s) SELECT * FROM `channel` WHERE (`title` = 'testTitle') LIMIT 1
I, [2014-06-14T02:51:45.267479 #79819]  INFO -- : (0.093502s) ROLLBACK
I, [2014-06-14T02:51:45.267736 #79819]  INFO -- : (0.000057s) BEGIN
E, [2014-06-14T02:51:45.268541 #79819] ERROR -- : SQLite3::ConstraintException: channel.title may not be NULL: INSERT INTO `channel` (`id`) VALUES ('testId2')
I, [2014-06-14T02:51:45.269063 #79819]  INFO -- : (0.000062s) ROLLBACK
I, [2014-06-14T02:51:48.328115 #79819]  INFO -- : (0.000048s) BEGIN
E, [2014-06-14T02:51:48.328812 #79819] ERROR -- : SQLite3::SQLException: no such table: main.videos: INSERT INTO `comment` DEFAULT VALUES
I, [2014-06-14T02:51:48.329058 #79819]  INFO -- : (0.000027s) ROLLBACK
I, [2014-06-14T02:51:48.329548 #79819]  INFO -- : (0.000022s) BEGIN
I, [2014-06-14T02:51:48.330584 #79819]  INFO -- : (0.000373s) INSERT INTO `user` (`username`) VALUES ('testName')
I, [2014-06-14T02:51:48.330885 #79819]  INFO -- : (0.000095s) SELECT * FROM `user` WHERE (`id` = 1) LIMIT 1
I, [2014-06-14T02:51:48.331049 #79819]  INFO -- : (0.000064s) SELECT * FROM `user` LIMIT 1
I, [2014-06-14T02:51:48.331875 #79819]  INFO -- : (0.000716s) ROLLBACK

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

你应该注意你的复数:

many_to_one应该指向您的表格的单数形式,foreign_key

class Video < Sequel::Model(:video)
  unrestrict_primary_key
  many_to_one :channel # <--
  many_to_many :comments
end

unless DB.table_exists? :comment
  DB.create_table :comment do
    primary_key :id
    foreign_key :user_id, :user # <--
    foreign_key :video_id, :video # <--
    integer     :likeCount, :default => 0
  end
end

class Comment < Sequel::Model(:comment)
  many_to_one :user # <--
  many_to_many :videos
end