首页 > 解决方案 > 如何从另一个表中的 id 到达表的列 rails

问题描述

我的项目中有 2 个表:交易和账户每笔交易“属于”一个账户。一个账户可以有很多交易。我相应地修改了模型文件。

    ActiveRecord::Schema.define(version: 2021_09_26_204408) do

  create_table "accounts", force: :cascade do |t|
    t.string "title"
    t.float "balance"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "transactions", force: :cascade do |t|
    t.string "title"
    t.float "value"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "notes"
    t.integer "account_id"
    t.index ["account_id"], name: "index_transactions_on_account_id"
  end

  add_foreign_key "transactions", "accounts"
end

这是我的帐户控制器

        class AccountsController
  def index
    @accounts = Account.all
  end

  def show
    @transaction = Transaction.find(params[:id])
    @account = Account.find_by(id: @transaction.account_id)
  end
end

我正在尝试为我的索引上显示的每笔交易显示帐户的标题。而且我希望能够将具有该 id 的每笔交易的价值相加以获得平衡。

我能够获得 transaction.account_id 但我无法深入到表格中。

我在我的 index.html.erb 中试过这个

<% @accounts.each do |account| %>
    <%= account.title %>
<% end %> 

但我得到@accounts 未定义或Nill。

路由.rb

Rails.application.routes.draw do
  root "transactions#index"

  resources :transactions
  resources :accounts
end

谢谢您的帮助

标签: ruby-on-railsactiverecordreferencehas-many

解决方案


首先,您似乎还没有所有交易都account_id存在。

要修复它,我建议像这样为事务表添加验证器而不是空声明

  create_table "transactions", force: :cascade do |t|
    ...
    t.integer "account_id",  null: false
    ... 
  end

这将保护您在没有数据库级别的帐户的情况下进行交易。

我看到的下一个问题是您正在通过索引操作获取帐户,但通过显示操作进行交易。

假设您有类似的模型

class Account < ApplicationRecord
  has_many :transactions
end

class Transaction < ApplicationRecord
  belongs_to :account
end

比您的帐户控制器看起来像

class AccountsController
  def index
    @accounts = Account.all
  end

  def show
    @account = Account.find(params[:id])
  end
end

比你可以通过模板循环呈现帐户,就像你做的那样。

关于每个帐户的交易总和的问题,我只会指导您了解它是如何工作的(尝试使用 rails 控制台检查下一个片段)

@accounts =  Account.joins(:transactions).select("accounts.* ,sum(transactions.value) as transactions_sum ").group("transactions.account_id")

@accounts.each do |account|
   puts account.title
   puts account.transactions_sum.to_s
end

类似的问题 has_many 总和活跃记录

最后一个错字 - 在数据库中使用小数来存储金额,而不是浮点数

祝你好运!


推荐阅读