【问题标题】:How to join tables in Ruby on Rails?如何在 Ruby on Rails 中连接表?
【发布时间】:2018-04-26 14:17:59
【问题描述】:

我有一张桌子residence_staffhalls。在residence_staff 表中有一个字段position,如果是经理,我想显示所有经理的列表和他们工作的hallName。我可以打印经理的名字就好了,但应用程序无法识别hallName。这些表使用staffNumber 作为halls 表中的外键连接到residence_staff 表中的staffNumber。我做错了什么?

residence_staff模特:

class ResidenceStaff < ApplicationRecord
  belongs_to :hall, primary_key: 'hallId'

  class << self

    def managers
      where(position: 'manager')
    end
  end
end

halls模特:

class Hall < ApplicationRecord
  has_many :residence_staffs
end

控制器:

class HomeController < ApplicationController

  def index
    @residence_staff = ResidenceStaff.all
    @residence_staff_managers = ResidenceStaff.managers.includes(:hall)
  end
end

查看:

<h1>Title</h1>

<div>
  <% @residence_staff_managers.each do |residence_staff| %>
    <%= residence_staff.fName%>
    <%= residence_staff.hallName%>
  <% end %>
</div>

Schema.rb:

ActiveRecord::Schema.define(version: 20180426051412) do

  create_table "advisor", primary_key: "advisorNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "fName", null: false
    t.text "lName", null: false
    t.text "position", null: false
    t.text "deptName", null: false
    t.integer "phoneNumber", null: false
    t.string "email", limit: 100, null: false
    t.integer "roomNumber", null: false
    t.index ["advisorNumber"], name: "Advisor_advisorNumber_uindex", unique: true
    t.index ["email"], name: "Advisor_email_uindex", unique: true
  end

  create_table "hall_of_residences", primary_key: "hallName", id: :string, limit: 50, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "street", limit: 50, null: false
    t.text "city", null: false
    t.integer "postcode", null: false
    t.integer "phoneNumber", null: false
    t.text "hall", null: false
    t.integer "staffNumber", null: false
    t.index ["hallName"], name: "HallOfResidence_hallName_uindex", unique: true
    t.index ["staffNumber"], name: "HallOfResidence_ResidenceStaff_staffNumber_fk"
  end

  create_table "halls", primary_key: "hallId", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "hallName", null: false
    t.text "street", null: false
    t.text "city", null: false
    t.integer "postcode", null: false
    t.integer "phoneNumber", null: false
    t.integer "sfaffNumber", null: false
    t.index ["sfaffNumber"], name: "halls_residence_staffs_staffNumber_fk"
  end

  create_table "invoice", primary_key: "invoiceNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "semester", limit: 50
    t.date "paymentDue"
    t.text "studentFName", null: false
    t.text "studentLName", null: false
    t.string "roomLocation", limit: 50, null: false
    t.text "city", null: false
    t.string "street", limit: 50, null: false
    t.integer "postcode", null: false
    t.integer "leaseNumber", null: false
    t.index ["invoiceNumber"], name: "Invoice_invoiceNumber_uindex", unique: true
    t.index ["leaseNumber"], name: "Invoice_Lease_leaseNumber_fk"
  end

  create_table "invoice_payment", primary_key: "paymentID", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.date "datePayed", null: false
    t.string "method", limit: 50, null: false
    t.date "dateOfFirstReminder"
    t.date "dateOfSecondReminder"
    t.integer "muNum", null: false
    t.index ["muNum"], name: "InvoicePayment_Student_mUNumber_fk"
    t.index ["paymentID"], name: "InvoicePayment_paymentID_uindex", unique: true
  end

  create_table "lease", id: false, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer "leaseNumber", null: false
    t.string "duration", limit: 50, null: false
    t.text "studentFName", null: false
    t.text "studentLName", null: false
    t.integer "placeNumber", null: false
    t.integer "roomNumber", null: false
    t.text "city", null: false
    t.string "street", limit: 50, null: false
    t.integer "postcode", null: false
    t.date "dateToLeave", null: false
    t.date "dateToEnter", null: false
    t.integer "mUNum", null: false
    t.index ["leaseNumber"], name: "Lease_leaseNumber_uindex", unique: true
    t.index ["mUNum"], name: "Lease_Student_mUNumber_fk"
    t.index ["placeNumber"], name: "Lease_placeNumber_uindex", unique: true
  end

  create_table "next_of_kin", primary_key: "nextID", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "fName", null: false
    t.text "lName", null: false
    t.text "relationship", null: false
    t.text "city", null: false
    t.string "street", limit: 100, null: false
    t.integer "postcode", null: false
    t.integer "phoneNumber", null: false
    t.integer "mUNum", null: false
    t.index ["mUNum"], name: "NextOfKin_Student_mUNumber_fk"
    t.index ["nextID"], name: "NextOfKin_nextID_uindex", unique: true
  end

  create_table "parking_lot", primary_key: "lotNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "lotName", null: false
    t.string "street", limit: 100, null: false
    t.text "city", null: false
    t.integer "postcode", null: false
    t.integer "maxSpace", null: false
    t.integer "availability", null: false
    t.index ["lotNumber"], name: "ParkingLot_lotNumber_uindex", unique: true
  end

  create_table "residence_staffs", primary_key: "staffNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "fName", null: false
    t.text "lName", null: false
    t.string "email", limit: 100, null: false
    t.text "homeCity", null: false
    t.string "street", limit: 50, null: false
    t.integer "postal", null: false
    t.date "dob", null: false
    t.text "gender"
    t.text "position", null: false
    t.string "location", limit: 50, null: false
    t.integer "phoneNumber", null: false
    t.integer "inspectedRoomID", null: false
    t.string "hall", limit: 50, null: false
    t.index ["inspectedRoomID"], name: "ResidenceStaff_StudentApartmentInspection_inspectedRoomID_fk"
    t.index ["staffNumber"], name: "ResidenceStaff_staffNumber_uindex", unique: true
  end

  create_table "room", primary_key: "placeNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "rentRate", limit: 50, null: false
    t.text "availability", null: false
    t.integer "roomNumber"
    t.string "hallName", limit: 50
    t.integer "apartmentNumber"
    t.index ["apartmentNumber"], name: "room_StudentFlats_apartmentNumber_fk"
    t.index ["hallName"], name: "room_HallOfResidence_hallName_fk"
  end

  create_table "staff", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.text "fName"
  end

  create_table "student", primary_key: "mUNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "fName", null: false
    t.text "lName", null: false
    t.string "street", limit: 100, null: false
    t.text "city", null: false
    t.integer "postcode", null: false
    t.integer "phoneNumber", null: false
    t.string "email", limit: 100, null: false
    t.date "dob", null: false
    t.text "gender"
    t.text "standing", null: false
    t.text "nationality", null: false
    t.string "specialNeeds", limit: 100
    t.text "major", null: false
    t.string "statusOfStudent", limit: 100
    t.text "minor"
    t.text "comments"
    t.integer "advisorNumber", null: false
    t.index ["advisorNumber"], name: "Student_Advisor_advisorNumber_fk"
    t.index ["email"], name: "Student_email_uindex", unique: true
    t.index ["mUNumber"], name: "Student_mUNumber_uindex", unique: true
  end

  create_table "student_apartment_inspection", primary_key: "inspectedRoomID", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.text "inspectorName", null: false
    t.date "dateOfInspection", null: false
    t.text "apartmentCondition", null: false
    t.text "comments"
    t.index ["inspectedRoomID"], name: "StudentApartmentInspection_inspectedRoomID_uindex", unique: true
  end

  create_table "student_flats", primary_key: "apartmentNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer "numberOfRooms", null: false
    t.text "city", null: false
    t.string "street", limit: 50, null: false
    t.integer "postcode", null: false
    t.integer "leaseID", null: false
    t.index ["apartmentNumber"], name: "StudentFlats_apartmentNumber_uindex", unique: true
    t.index ["leaseID"], name: "StudentFlats_Lease_leaseNumber_fk"
  end

  create_table "vehicle", primary_key: "vNumber", id: :integer, default: nil, force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.string "plateNumber", limit: 10, null: false
    t.text "color", null: false
    t.text "manufacturer", null: false
    t.string "brand", limit: 50, null: false
    t.integer "mUNum", null: false
    t.integer "lotNumber", null: false
    t.index ["lotNumber"], name: "Vehicle_ParkingLot_lotNumber_fk"
    t.index ["mUNum"], name: "Vehicle_Student_mUNumber_fk"
    t.index ["plateNumber"], name: "Vehicle_plateNumber_uindex", unique: true
    t.index ["vNumber"], name: "Vehicle_vNumber_uindex", unique: true
  end

  add_foreign_key "hall_of_residences", "residence_staffs", column: "staffNumber", primary_key: "staffNumber", name: "HallOfResidence_ResidenceStaff_staffNumber_fk"
  add_foreign_key "halls", "residence_staffs", column: "sfaffNumber", primary_key: "staffNumber", name: "halls_residence_staffs_staffNumber_fk"
  add_foreign_key "invoice", "lease", column: "leaseNumber", primary_key: "leaseNumber", name: "Invoice_Lease_leaseNumber_fk"
  add_foreign_key "invoice_payment", "student", column: "muNum", primary_key: "mUNumber", name: "InvoicePayment_Student_mUNumber_fk"
  add_foreign_key "lease", "student", column: "mUNum", primary_key: "mUNumber", name: "Lease_Student_mUNumber_fk"
  add_foreign_key "next_of_kin", "student", column: "mUNum", primary_key: "mUNumber", name: "NextOfKin_Student_mUNumber_fk"
  add_foreign_key "residence_staffs", "student_apartment_inspection", column: "inspectedRoomID", primary_key: "inspectedRoomID", name: "ResidenceStaff_StudentApartmentInspection_inspectedRoomID_fk"
  add_foreign_key "room", "hall_of_residences", column: "hallName", primary_key: "hallName", name: "room_HallOfResidence_hallName_fk"
  add_foreign_key "room", "student_flats", column: "apartmentNumber", primary_key: "apartmentNumber", name: "room_StudentFlats_apartmentNumber_fk"
  add_foreign_key "student", "advisor", column: "advisorNumber", primary_key: "advisorNumber", name: "Student_Advisor_advisorNumber_fk"
  add_foreign_key "student_flats", "lease", column: "leaseID", primary_key: "leaseNumber", name: "StudentFlats_Lease_leaseNumber_fk"
  add_foreign_key "vehicle", "parking_lot", column: "lotNumber", primary_key: "lotNumber", name: "Vehicle_ParkingLot_lotNumber_fk"
  add_foreign_key "vehicle", "student", column: "mUNum", primary_key: "mUNumber", name: "Vehicle_Student_mUNumber_fk"
end

【问题讨论】:

    标签: mysql ruby-on-rails database model-view-controller mariadb


    【解决方案1】:

    使用&lt;%= residence_staff.hall.hallName %&gt; 代替&lt;%= residence_staff.hallName %&gt;,因为hallNamehall 的一个属性。

    顺便说一句,ruby 命名约定有利于蛇形大小写。 hallName 将改为 hall_name

    【讨论】:

    • 好的,我这样做了,现在我收到了这个错误:Mysql2::Error: Unknown column 'residence_staffs.hall_id' in 'on clause': SELECT residence_staffs.* FROM residence_staffs INNER JOIN halls ON halls.hallId = residence_staffs.hall_id WHERE residence_staffs.position = '经理'
    • 我相信这是因为 Rails 中使用的命名约定。您可以覆盖它,但最好将 hallId 重命名为 hall_id > Rails 期望数据库中的外键具有 _id 后缀,如果名称对齐,它将自动映射到这些键的关系。跨度>
    • 这一行 belongs_to :hall, primary_key: 'hallId' 与您的架构不匹配 t.string "hall", limit: 50, null: false 应该是一个名为 hall_id 的整数。您可以在rails console (rails c) 中进行测试。当您可以正确输入ResidenceStaff.first.hall 时,它已正确连接。
    猜你喜欢
    • 2011-05-10
    • 2010-10-20
    • 1970-01-01
    • 2011-11-28
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多