【发布时间】:2012-03-30 16:15:41
【问题描述】:
想象一下,我有一个团队中许多成员都可以看到的待办事项列表。我想让每个团队成员根据他们认为最重要的待办事项来维护自己的待办事项列表顺序。
如何在数据库级别存储此排序?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 database-design activerecord sql-order-by
想象一下,我有一个团队中许多成员都可以看到的待办事项列表。我想让每个团队成员根据他们认为最重要的待办事项来维护自己的待办事项列表顺序。
如何在数据库级别存储此排序?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 database-design activerecord sql-order-by
我会将订单作为浮点数(可能称为“位置”或类似名称)存储在连接用户和待办事项的连接表中。然后,当您获取列表时,您可以在关系中指定该顺序。使用 :has_many :through 关系的主要原因之一是当您想要存储有关关联本身的数据(而不是任何一个关联模型)时。
【讨论】:
您将需要一个与用户和待办事项相关联的单独模型。例如。 (假设您现有的模型称为 User 和 Todo:
app/models/todo_orders.rb
class TodoOrders.rb < ActiveRecord::Base
belongs_to :user
belongs_to :todo
validates_uniqueness_of :order_num
end
db/migrate/yyyymmddhhmmss_create_todo_orders.rb
def up
t.integer :user:id
t.integer :todo_id
t.integer :order_num
end
您需要在模型中添加一些额外的逻辑来提取正确的订单并将它们与您的待办事项相关联。例如
app/models/todo.rb
attr_accessor :cur_order
app/models/user.rb
has_many :todo_orders
def get_todos
todo_orders.includes(:todo).map do |todo_order|
todo = todo_order.todo
todo.cur_order = todo_order.order_num
todo
end
end
因此,在用户对象上调用 get_todos 将返回一个 Todos 列表,其中要显示的顺序存储在其 cur_order 属性中
【讨论】:
您的数据库模型应如下所示:
这是一个非常标准的多对多关系,中间是“链接”表,但有一个转折点:ORDER 是备用键 {USER_ID, ORDER} 的一部分(在上图)但不是主键的一部分。这就是它按用户排序的原因。
(免责声明:我不熟悉 Ruby on Rails - 这个答案纯粹是从数据库建模的角度来看。)
【讨论】: