活动记录::记录无效:验证失败:团队必须存在



当我运行rake db:seed时,我收到错误ActiveRecord::RecordInvalid: Validation failed: Team must exist

我正在尝试在球员和球队之间建立关联。我有要向数据库播种的数据,但我不确定错误是由我设置关联的方式还是结构化数据的方式引起的。

团队是父母,球员是孩子。

模型

# player.rb
class Player < ApplicationRecord
belongs_to :team, class_name: "Player"
validates :team, presence: true, allow_nil: true
end

# team.rb
class Team < ApplicationRecord
has_many :players
end

路线

# routes.rb
Rails.application.routes.draw do
get 'welcome/index'
resources :players
resources :teams do
resources :players
end
root 'welcome#index'
end

迁移

# create_players.rb
class CreatePlayers < ActiveRecord::Migration[5.1]
def change
create_table :players do |t|
t.belongs_to :team, index: true
t.string :name
t.string :shoots
t.string :catches
t.string :position
t.string :pos
t.integer :number
t.integer :gp
t.integer :goals
t.integer :assists
t.integer :points
t.integer :pim
t.integer :plusMinus
t.decimal :gaa
t.integer :svs
t.integer :team_id
t.references :teams
t.timestamps
end
end
end

# create_teams.rb
class CreateTeams < ActiveRecord::Migration[5.1]
def change
create_table :teams do |t|
t.string :team_name
t.string :abr
t.string :sm_logo
t.string :lg_logo
t.integer :player_id
t.timestamps
end
end
end

尝试设定种子的数据的数据示例

# Player data
players = Player.create!({
"name": "Some Guy",
"shoots": "Right",
"position": "Forward",
"pos": "F",
"number": 8,
"gp": 15,
"goals": 12,
"assists": 6,
"points": 18,
"pim": 12,
"plusMinus": 7,
"team_id": 1
})

# Team data
teams = Team.create!({
"team_name": "A Team",
"abr": "ATM"
})

宝石文件

source 'https://rubygems.org'
gem 'rails', '~> 5.1.0'
gem 'pg', '~> 0.18'
gem 'puma', '~> 3.7'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
#Bootstrap 4 and Tether gems
gem 'bootstrap', '~> 4.0.0.alpha6'
gem 'rails-assets-tether', '>= 1.3.3', source: 'https://rails-assets.org'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'rails-ujs', '~> 0.1.0'
gem 'jquery-rails'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end
group :development do
# Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

首先,您需要创建团队:

team = Team.create!({ team_name: "A Team", abr: "ATM" })

请注意,我将hash传递给create!方法,而不是像示例中那样传递带有哈希的array

然后,您可以创建玩家并将其添加到团队中:

player = Player.create!({
"name": "Some Guy",
"shoots": "Right",
"position": "Forward",
"pos": "F",
"number": 8,
"gp": 15,
"goals": 12,
"assists": 6,
"points": 18,
"pim": 12,
"plusMinus": 7,
"team": team
})

请注意,我能够将team对象传递给Player.create!方法。这会将玩家与团队相关联。否则,您可以只使用 id。

player = Player.create!({
...
team_id: team.id
})

player = Player.create!({
...
team_id: 1
})

省略号(3 个点)应替换为实际属性,如上所示。

更新

create_players.rb迁移中删除以下行:

t.integer :teams_id
t.references :teams

create_teams.rb迁移中删除以下行:

t.integer :player__id

写入t.belongs_to :player产生与写入t.integer :player_id相同的结果。这只是Rails的语法糖。写t.belongs_to :playert.references :player比写t.integer :player_id更清楚一点

我假设您希望一名球员属于一支球队(一对多关系)。如果你认为一个球员可能属于多个团队(通常不是这样,但我不知道你在开发什么),那么你就需要在谷歌上搜索Rails的多对多关系。

@Greg 回答 谢谢你的帮助。我现在已经找到了一个可行的解决方案。

为了修复,我恢复到以前的提交,并决定遵循以下文章: https://www.learneroo.com/modules/137/nodes/767

我完成的工作代码如下所示:

模型

# Team model
class Team < ApplicationRecord
has_many :players
end
# Player model
class Player < ApplicationRecord
belongs_to :team
end

迁移

# create_teams.rb
class CreateTeams < ActiveRecord::Migration[5.1]
def change
create_table :teams do |t|
t.string :team_name
t.string :abr
t.timestamps
end
end
end
# create_players.rb
class CreatePlayers < ActiveRecord::Migration[5.1]
def change
create_table :players do |t|
t.string :name
t.string :shoots
t.string :catches
t.string :position
t.string :posAbr
t.string :abr
t.integer :number
t.integer :gp
t.integer :goals
t.integer :assists
t.integer :points
t.integer :pim
t.integer :plusMinus
t.decimal :gaa
t.integer :svs
t.timestamps
end
end
end
# add_team_id_to_players.rb
class AddTeamIdToPlayers < ActiveRecord::Migration[5.1]
def change
add_column :players, :team_id, :integer
end
end

种子数据示例

# Team data
teams = Team.create([{
"team_name": "A Team",
"abr": "ATM"
}])
# Player data
players = Player.create!([{
"name": "Some Guy",
"shoots": "Right",
"position": "Forward",
"pos": "F",
"number": 8,
"gp": 15,
"goals": 12,
"assists": 6,
"points": 18,
"pim": 12,
"plusMinus": 7,
"team_id": 1
}])

您在class Player中的关联是错误的,请参阅何时必须使用:

如果无法从关联名称派生其他模型的名称,则可以使用 :class_name 选项提供模型名称。例如,如果一本书属于作者,但包含作者的模型的实际名称是 Patron,则可以按以下方式进行设置:

class Book < ApplicationRecord
belongs_to :author, class_name: "Patron"
end

查看使用此关联的所有选项:导轨指南

最新更新