【问题标题】:Associating two columns in the same Model class to the same column in another Model - Rails将同一模型类中的两列关联到另一个模型中的同一列 - Rails
【发布时间】:2018-05-31 14:23:16
【问题描述】:

快速提问 - 我有两个模型类 - TransactionsAccounts

帐户模型如下所示:

 create_table "accounts", force: :cascade do |t|
    t.string   "account_name"
    t.integer  "account_number"
    t.boolean  "current_asset"
    t.boolean  "non_current_asset"
    t.boolean  "current_liability"
    t.boolean  "non_current_liability"
    t.boolean  "equity"
    t.boolean  "cost_of_sales"
    t.boolean  "operating_expense"
    t.boolean  "sales"
    t.boolean  "other_income"
    t.boolean  "bank"
    t.datetime "created_at",            null: false
    t.datetime "updated_at",            null: false
    t.integer  "user_id"
  end

交易模型如下所示:

 create_table "transactions", force: :cascade do |t|
    t.date     "date"
    t.string   "description"
    t.string   "reference"
    t.integer  "amount"
    t.integer  "account_id"
    t.boolean  "payment"
    t.boolean  "receipt"
    t.integer  "bank_id"
    t.datetime "created_at",          null: false
    t.datetime "updated_at",          null: false
    t.integer  "user_id"
    t.boolean  "vat"
    t.integer  "vat_amount"
    t.integer  "transaction_form_id"
    t.integer  "contact_id"
  end

用户添加了一个新事务,该事务通过 collection_select 他们选择一个显示所有帐户的帐户,除了 bank == true (其中bank == true 它代表一个银行帐户)。

当用户选择银行时,他们只能选择银行账户 - bank==true(再次通过集合选择)。

我需要运行一个方法,允许我通过基于 bank_id 而不是 account_id 的 Account 模型调用所有交易金额。那么我如何通过 account_id 或 bank_id 将我的 Transaction 模型的两个不同列与 Accounts 类中的同一列相关联。

该方法看起来像:

<% Account.each do |account| %>
<% if account.bank == true && account.transaction(:bank_id) == account.id %>
<%= account.number %>
<%= account.number %>
<%= account.transactions.sum(:amount) %>
<% end %>

Ps:我知道这是我的观点,而不是控制器,但这是另一个讨论!

An image of Models example

【问题讨论】:

  • 你能贴出两个模型的代码来描述它们之间的关系吗? (belongs_to/has_many)

标签: ruby-on-rails


【解决方案1】:

我建议您备份并重新考虑您的方法。

银行账户和 GL 账户是完全不同的东西(尽管它们都使用“账户”这个词)。使用单个模型来表示这两者会导致混乱和大量空白字段。考虑使用BankAccountGLAccount(您可以在GLAccount 上使用自定义inflection,如果您愿意,也可以使用gl_account)。

如果您使用BankAccountGLAccount,那么您可以简单地对您的Transaction 模型进行多态关联,例如:

class Transaction < ActiveRecord::Base
  belongs_to :account, polymorphic: true
end

您需要更改 transactions 表以包含 account_typeaccount_id 才能正常工作。

然后,您的 BankAccountGLAccount 模型将如下所示:

class BankAccount < ActiveRecord::Base
  has_many :transactions, as: :account
end

class GLAccount < ActiveRecord::Base
  has_many :transactions, as: :account
end

在这种情况下,要迭代 BankAccounts,您可以执行以下操作:

<% BankAccount.all.each do |bank_account| %>
  <%= bank_account.number %>
  <%= bank_account.transactions.sum(:amount) %>
<% end %>

这将导致 N+1 查询问题,但您可以单独解决。

顺便说一句,在您的 GL 帐户上,您应该使用 enums 作为帐户类型。正如您当前设置的那样,您将总是有 8 个空的布尔字段(不好)。这可能看起来像:

class GLAccount < ActiveRecord::Base
  has_many :transactions, as: :account

  enum account_type: {
    current_asset:          0,
    non_current_asset:      1,
    current_liability:      2,
    non_current_liability:  3,
    equity:                 4,
    cost_of_sales:          5,
    operating_expense:      6,
    sales:                  7,
    other_income:           8
  }

end

您的gl_accounts 表需要包含account_type 作为整数才能工作。

其他一些随机笔记:

  • if account.bank == true 应该只是 if account.bank
  • 你重复&lt;%= account.number %&gt;

但是,鉴于您所做的,您可以执行以下操作:

class Account < ActiveRecord::Base
  has_many bank_transactions, class_name: 'Transaction', foreign_key: :bank_id
end

在这种情况下,你应该能够做到:

<% Account.where(bank: true).each do |bank_account| %>
  <%= bank_account.number %>
  <%= bank_account.bank_transactions.sum(:amount) %>
<% end %>

【讨论】:

  • 我无法告诉你我刚刚从这个答案中学到了多少!我对这一切都很陌生,非常感谢这样的答案!
  • 太棒了!随时为未来的搜索者投票/接受。
  • 从表面上看 - 您了解会计系统及其结构的方式 - 关于与此相关的任何资源的任何建议?如果这超出了问题和论坛的范围,我们深表歉意。
  • 是的,我有很多使用会计系统的经验——使用、配置和集成。你心目中的资源是什么?
  • 有任何关于使用 Rails 的会计/企业系统的阅读材料吗?我来自会计背景 - 但软件方面的事情显然有点棘手!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-23
  • 1970-01-01
相关资源
最近更新 更多