Ruby on rails 数据库设计/Rails-两个用户之间的平衡设计
我正在寻找一种在RubyonRails中设计两个用户之间平衡模型的方法(但可能更通用)。两个用户Alice和Bob将从一个值为零的余额开始,与另一个用户相比。现在,如果Alice得到+4,我希望Bob得到-4。以下是我到目前为止的想法:Ruby on rails 数据库设计/Rails-两个用户之间的平衡设计,ruby-on-rails,ruby,relational-database,Ruby On Rails,Ruby,Relational Database,我正在寻找一种在RubyonRails中设计两个用户之间平衡模型的方法(但可能更通用)。两个用户Alice和Bob将从一个值为零的余额开始,与另一个用户相比。现在,如果Alice得到+4,我希望Bob得到-4。以下是我到目前为止的想法: 有三个字段的余额:user\u one、user\u two和one\u to\u two。也就是说,如果我想要用户1到用户2的平衡,我只需要1到2,如果我想要从2到1,我需要-1到2(只是平衡模型中的一个方法)。问题是,我不能简单地使用用户模型中的“has_
- 有三个字段的余额:user\u one、user\u two和one\u to\u two。也就是说,如果我想要用户1到用户2的平衡,我只需要1到2,如果我想要从2到1,我需要-1到2(只是平衡模型中的一个方法)。问题是,我不能简单地使用用户模型中的“has_many balances through”,因为余额需要知道是User_one还是User_two在呼叫(我必须传递该用户)
- 又是一个带有三个字段的平衡,但完全不对称:如果我为Alice到Bob创建一个平衡,我必须创建另一个从Bob到Alice的平衡实例。这将使数据库中每个“余额”所需的存储量增加一倍,并且每次我将alice\u更新为\u bob时都需要将bob\u更新为\u alice
有没有人能想出更好的办法,或者解释一下选择上述方法的原因?如果我能说得更清楚,请告诉我。所以,我想我找到了一些非常整洁的东西。它使用了这样一个事实:用户alice总是id最小的用户(via:sure\u alice\u before\u bob)。剩下的应该是清楚的 用户模型只有两个额外的“has_many:balances_as_alice,has_many:balances_as_bob”。它只能使用一个(例如:balances\u as\u alice),但使用这两个present+dependent::destroy时,请确保避免孤立余额
# == Schema Information
#
# Table name: balances
#
# id :integer not null, primary key
# alice_id :integer not null
# bob_id :integer not null
# alice_value :float default("0.0")
# created_at :datetime not null
# updated_at :datetime not null
#
class Balance < ActiveRecord::Base
belongs_to :alice, class_name: 'User'
belongs_to :bob, class_name: 'User'
before_validation :ensure_alice_before_bob
validates :alice_id, presence: true
validates :bob_id, presence: true, uniqueness: { scope: :alice_id}
validate :different_users
def value
@for_bob ? -alice_value : alice_value
end
def value=(new_val)
@for_bob? self.alice_value = -new_val : self.alice_value = new_val
end
def Balance.get_for alice, bob
user = 'alice'
alice, bob, user = bob, alice, 'bob' if alice.id > bob.id
balance= alice.balances_as_alice.find_by(bob: bob) ||
Balance.new(bob: bob, alice: alice, alice_value: 0.0)
balance.send("for_#{user}")
end
def for_bob
@for_bob = true; self
end
def for_alice
@for_bob = false; self
end
private
def ensure_alice_before_bob
return if self.alice_id.nil? || self.bob_id.nil?
unless self.alice_id < self.bob_id
self.bob_id, self.alice_id = self.alice_id, self.bob_id
end
end
def different_users
if self.alice_id == self.bob_id
errors.add(:bob_id, "Cannot be the same user")
end
end
end
#==架构信息
#
#表名:余额
#
#id:整数不为空,主键
#alice_id:整数不为空
#bob_id:整数不为空
#alice_值:浮动默认值(“0.0”)
#创建时间:datetime非空
#更新时间:datetime非空
#
类余额bob.id
balance=alice.balances_as_alice.find_by(bob:bob)|
Balance.new(bob:bob,alice:alice,alice_值:0.0)
balance.send(“for#{user}”)
终止
鲍勃的def
@for_bob=true;自己
终止
艾丽丝的def
@for_bob=false;自己
终止
私有的
在bob之前确保alice
如果self.alice|u id.nil?|返回self.bob_id.nil?
除非self.alice\u id