【问题标题】:Rails model joined has_manyRails 模型加入 has_many
【发布时间】:2013-02-22 10:59:29
【问题描述】:

这是我想要做的:

class Cashflow < ActiveRecord::Base
    belongs_to from_account, :class_name => 'Account'
    belongs_to to_account, :class_name => 'Account'
end

class Account < ActiveRecord::Base
    has_many :cashflows
end

其中Account::cashflows 显然是所有cashflows 的列表,这些account_id 存储在from_accountto_account 中。

我很困惑。处理这种情况的正确方法是什么?这是多么糟糕的设计?设计这种关系的正确方法是什么?

【问题讨论】:

    标签: ruby-on-rails model model-associations


    【解决方案1】:

    我认为您的结构正确,因为特定交易/现金流只能涉及两个账户。如果您使用多对多关联,则需要处理不涉及多于或少于 2 个帐户的验证。对于您当前的结构,您可以将您的模型关联更改为:

    class Cashflow < ActiveRecord::Base
      belongs_to from_account, :class_name => 'Account', :foreign_key => :from_account
      belongs_to to_account, :class_name => 'Account', :foreign_key => :to_account
    end
    
    class Account < ActiveRecord::Base
      has_many :debits, :class_name => 'Cashflow', :foreign_key => :from_account
      has_many :credits, :class_name => 'Cashflow', :foreign_key => :to_account
    
      def cashflows
        transactions = []
        transactions << self.debits
        transactions << self.credits
        transactions.flatten!
    
        ## or may be the following commented way
        # Cashflow.where('from_account = ? OR to_account = ?', self.id, self.id)
      end
    end
    

    通过这种方式,您可以跟踪特定账户中借记/贷记的金额,并获得参与特定交易/现金流的账户。

    【讨论】:

    • 听起来不错。现在,我有大量的对象需要做account.cashflows。我想我可以为此使用范围。你有什么建议?
    • 另外一个问题是:你如何获得签名现金流的列表。就像account.cashflows 的现金流对给定帐户具有签名值?!这是一个棘手的问题。 ://
    • 如果您创建一个关联,那么它将在cashflows 表中查找account_id。如果你创建了一个作用域,那么你就不能在模型实例上使用它,所以你需要创建一个方法cashflows。你所说的签名现金流是什么意思?
    • 我在回答中添加了cashflows 方法。
    • 关于范围与方法。您可以通过创建范围并从方法内部调用它来完成这两者。因此,您可以根据需要访问它,并且仍然有 1 行。你只需要有两个名字。
    【解决方案2】:

    我心中的建议

    1) 您的班级(表)cashflows 应该有两列 from_account 和 to_account。

    2) from_accountto_account 应该有相关帐户的 id

    3) cashflows 应该是 belongs_to :account

    4) account 应该是 has_many :cashflows。理想情况下应该是cash_flows

    这些应该是很好的起点。它们不符合您的要求吗?

    【讨论】:

    • 是的,先生!除了 4,但我认为命名约定不会影响这里。
    • @Arindam 模型类是 Cashflow 而不是 CashFlow 所以关联名称是正确的。
    • 对。错过了。谢谢
    【解决方案3】:

    我认为你应该在这里使用 has 和 belongs to many 关联:

    class Account < ActiveRecord::Base
      has_and_belongs_to_many :incoming_cashflows, :class_name => 'Cashflow', :join_table => :incoming_cashflows_accounts
      has_and_belongs_to_many :outcoming_cashflows, :class_name => 'Cashflow', :join_table => :outcoming_cashflows_accounts
    end
    
    class Cashflow < ActiveRecord::Base
      has_and_belongs_to_many :from_accounts, :class_name => 'Account', :join_table => :incoming_cashflows_accounts
      has_and_belongs_to_many :to_accounts, :class_name => 'Account', :join_table => :outcoming_cashflows_accounts
    end
    

    此外,您还需要一些验证码,以便仅将一个帐户添加到 Cashflow。

    【讨论】:

    • 这就是我首先想到的。现在你的解决方案的麻烦是你无法区分现金流的方向。 Cashflow 有一个 :amount 字段,该字段带有一个值,该值对 from_account 负数,对 to_account 正数。有什么想法吗?
    • 我认为你可以很容易地解决这个问题 - 添加 get_direction 之类的方法,它将根据 :from_accounts 和 :to_accounts 项目计数返回结果。在现金流入时,to_accounts.count 将始终为 0,在流出时 - from_accounts.count 将始终为 0。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-29
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多