使用Ruby Sequel清理关联定义

时间:2012-08-01 00:33:23

标签: ruby coding-style sequel

我正在使用Jeremy Evan的Sequel来填充(SQLite)数据库,其中包含我从网页中搜集的数据。 数据库涉及我用Associations表达的许多多对多关系。 关联是在类定义中创建的,在运行脚本时始终会对其进行评估。 重要的是,关联类定义需要具有必要的表。 因此,表创建方法应该在关联定义的顶层。 这是一个例子:

module Thing
db = Sequel.Sqlite('data.sqlite')

db.create_table(:clients)
    String :client_id, :primary_key => true
    String :client_data
end

db.create_table(:orders)
    String :order_id, :primary_key => true
    String :order_data
end

db.create_table(:orders_clients)
    String :order_id
    String :client_id
    primary_key [:order_id,:client_id]
end

class Person < Sequel::Model
    unrestrict_primary_key
    many_to_many :orders
end

class Order < Sequel::Model
    unrestrict_primary_key
    many_to_many :orders
end
end

首先,我认为这是一个相当脏的解决方案,因为我的方法调用和类定义位于同一个命名空间中。 如果我尝试分离类定义,我会得到No database associated with Sequel::Model错误(这是有道理的,但我想推迟对关联定义的评估,在表调用之后,只要它们可能发生)。

我希望能够在方法调用中创建表和关联。因此,我可以传递新数据库文件的名称:

def create_tables_and_schema (database_name)
    db = Sequel.Sqlite(database_name)
    db.create_table... #three of those, as above

class Person < Sequel::Model
    unrestrict_primary_key
    many_to_many :orders
end

class Order < Sequel::Model
    unrestrict_primary_key
    many_to_many :orders
end
end

我认为需要的是表达表关系的另一种方式。

对方法和风格的任何建议都表示赞赏。如果解释令人困惑,请询问澄清。

1 个答案:

答案 0 :(得分:5)

您的方法调用和类定义不需要位于同一名称空间中,只需要在模型类之前创建表。分离它们的一种简单方法是将表创建移动到单独的文件中。此外,通常将数据库对象分配给常量。

create_tables.rb:

DB.create_table(:clients)
  String :client_id, :primary_key => true
  String :client_data
end

DB.create_table(:orders)
  String :order_id, :primary_key => true
  String :order_data
end

DB.create_table(:orders_clients)
  String :order_id
  String :client_id
  primary_key [:order_id,:client_id]
end

models.rb:

DB = Sequel.sqlite('data.sqlite')
require 'create_tables'

class Person < Sequel::Model
  unrestrict_primary_key
  many_to_many :orders
end

class Order < Sequel::Model
  unrestrict_primary_key
  many_to_many :orders
end

您提到要在方法调用中创建表和关联,但如果要创建具有常量的类则没有意义。通过方法调用创建它们的主要原因是在运行时允许多个数据库,但这不适用于您的模型类,因为它们是使用常量名称定义的。

如果在运行时不需要多个数据库,如果您只想将表创建与模型创建分开,上面的示例应该有效。

如果在运行时确实需要多个数据库,那么通过方法调用创建表和模型是有意义的,但是您需要创建匿名模型类,否则您将遇到问题。