我正在使用:rails 6.1.4
和ruby 3.1.1p18
我已经有一分钟没有在Rails中使用多对多的关联了,我对这个有点迷失。任何帮助/提示将不胜感激。
我很乐意编辑后添加更多的信息,如果要求。
我在rails应用程序living_muay_thai/
中创建了一个目录,并试图在其中创建两个模型之间的many to many
关系。我有所有的代码。使用console (development)
,我尝试在joins表中创建一个记录,我得到一个错误:
3.1.1 :009 > sb.errors.full_messages
=> ["Living muay thai student must exist", "Living muay thai badge must exist"]
我的代码:
generate models/migrations:
rails generate model living_muay_thai/Student
rails generate model living_muay_thai/Badge
现在我不记得我是如何创建连接表的了。我想我尝试了几个不同的生成行,但都以索引名称太长的错误结束,所以我最终手动编辑它以使错误变得愉快。
Migrations:
Students:
class CreateLivingMuayThaiStudents < ActiveRecord::Migration[6.1]
def change
create_table :living_muay_thai_students do |t|
t.string :fname
t.string :lname
t.timestamps
end
end
end
--------------------------
Badges:
class CreateLivingMuayThaiBadges < ActiveRecord::Migration[6.1]
def up
create_table :living_muay_thai_badges do |t|
t.string :color
t.string :category
t.integer :number
t.timestamps
end
end
def down
drop_table :living_muay_thai_badges
end
end
------------------
StudentBadges (joins table)
class CreateLivingMuayThaiStudentBadges < ActiveRecord::Migration[6.1]
def change
create_table :living_muay_thai_student_badges do |t|
t.integer :student_id
t.integer :badge_id
t.timestamps
end
add_index :living_muay_thai_student_badges, :student_id, name: 'students_index'
add_index :living_muay_thai_student_badges, :badge_id, name: 'badges_index'
end
end
对于学生徽章迁移,我这样做了(上面),因为这样做的方式一对夫妇的教程提到我得到一个错误... Index name too long...
这样就成功了
Models:
Students:
# == Schema Information
#
# Table name: living_muay_thai_students
#
# id :bigint not null, primary key
# fname :string
# lname :string
# created_at :datetime not null
# updated_at :datetime not null
#
class LivingMuayThai::Student < ApplicationRecord
has_many :living_muay_thai_student_badges
has_many :living_muay_thai_badges, through: :living_muay_thai_student_badges
has_many :living_muay_thai_levels
end
----------------------
Badges:
# == Schema Information
#
# Table name: living_muay_thai_badges
#
# id :bigint not null, primary key
# category :string
# color :string
# number :integer
# created_at :datetime not null
# updated_at :datetime not null
#
class LivingMuayThai::Badge < ApplicationRecord
has_many :living_muay_thai_student_badges
has_many :living_muay_thai_students, through: :living_muay_thai_student_badges
end
---------------------
StudentBadge
# == Schema Information
#
# Table name: living_muay_thai_student_badges
#
# id :bigint not null, primary key
# badge_id :integer
# student_id :integer
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# badges_index (badge_id)
# students_index (student_id)
#
class LivingMuayThai::StudentBadge < ApplicationRecord
belongs_to :living_muay_thai_student
belongs_to :living_muay_thai_badge
end
我还没把控制器具体化。我想在这之前在控制台上测试一下。我不确定这和我的问题有什么因果关系。(??)
控制台:
# create a student:
3.1.1 :001 > s1=LivingMuayThai::Student.create(:fname => 'John', :lname=>'Smith')
# works
# create a badge:
3.1.1 :002 > b1=LivingMuayThai::Badge.create(:color => 'White', :category => 'Beginner', :number => 1)
# works
# create record in joins table:
3.1.1 :003 > sb=LivingMuayThai::StudentBadge.create(:student_id => s1.id, :badge_id => b1.id)
=> #<LivingMuayThai::StudentBadge:0x00007f713867a970 id: nil, student_id: 11, badge_id: 140, created_at: nil, updated_at: nil>
3.1.1 :004 > sb.valid?
=> false
3.1.1 :005 > sb.errors.full_messages
=> ["Living muay thai student must exist", "Living muay thai badge must exist"]
再次感谢你看这个。非常感谢。
1条答案
按热度按时间lawou6xi1#
问题在于如何定义关联以及具有哪些列和表名称。现在它们不符合Rails约定
使用连接表的显式列名定义
belongs_to
:也可以重命名列名。在这种情况下,不需要指定
:foreign_key
选项第二个选项是根据列名更改关联名称(并保持列名不变(student_id和badge_id):