我有两个模型,任务和单位。任务has_many:单位。我想根据某种优先顺序订购单位。例如:有两个单元A和B.必须在B之前完成。用户可以在A和B之间添加另一个单元,例如C,然后也可以删除单元C - A和B的优先级将保持不变。什么是在Rails中实现这一点的最简单/直接的方式?
我考虑过的想法:
将一个优先整数列添加到units表中,该表在任何更改单位集合的操作上都会更新。
将自连接关联添加到指向下一个/上一个单元的单元模型,并在更改单元集合时修改关联。
答案 0 :(得分:1)
对问题进行建模的正确方法取决于您的任务结构的复杂程度。
如果任务的单位总是可以按照倒数第一的顺序排列,那么为每个单位提供一个整数顺序,可以最简单地将单位置于该顺序中,在ActiveRecord中使用order
或sort
在记忆中。唯一的缺点是,当您添加或删除单位时,您可能需要保存其他单位以更新其订单。如果任务具有小的整数数量的单位,那可能不是一个很大的缺点。
如果任务可以有循环,则每个单元都需要对其前面的单元的引用。您甚至可能最终需要一个模型来表示单元与其后的单元之间的关系。因此,请仔细考虑您希望支持的用例,看看哪些适用。
答案 1 :(得分:0)
您可以使用acts_as_votable gem。 此迁移可以解决您的问题:
class AddCachedVotesToPosts < ActiveRecord::Migration
def self.up
add_column :posts, :cached_votes_total, :integer, :default => 0
add_column :posts, :cached_votes_score, :integer, :default => 0
add_column :posts, :cached_votes_up, :integer, :default => 0
add_column :posts, :cached_votes_down, :integer, :default => 0
add_column :posts, :cached_weighted_score, :integer, :default => 0
add_column :posts, :cached_weighted_total, :integer, :default => 0
add_column :posts, :cached_weighted_average, :float, :default => 0.0
add_index :posts, :cached_votes_total
add_index :posts, :cached_votes_score
add_index :posts, :cached_votes_up
add_index :posts, :cached_votes_down
add_index :posts, :cached_weighted_score
add_index :posts, :cached_weighted_total
add_index :posts, :cached_weighted_average
# Uncomment this line to force caching of existing votes
# Post.find_each(&:update_cached_votes)
end
def self.down
remove_column :posts, :cached_votes_total
remove_column :posts, :cached_votes_score
remove_column :posts, :cached_votes_up
remove_column :posts, :cached_votes_down
remove_column :posts, :cached_weighted_score
remove_column :posts, :cached_weighted_total
remove_column :posts, :cached_weighted_average
end
end
特别是此列add_column :posts, :cached_votes_up, :integer, :default => 0
和此索引add_index :posts, :cached_votes_score