ActiveRecord :: RecordInvalid:验证失败:团队必须存在

时间:2017-05-11 14:20:00

标签: postgresql activerecord ruby-on-rails-5

运行rake db:seed时收到错误# 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]

的Gemfile

FROM centos

ENV http_proxy=my.proxy.url \ 
    https_proxy=my.proxy.url \

# these lines required for the proxy to be trusted, most apps block it otherwise b/c SSL inspection
COPY ./certs/*.pem /etc/pki/ca-trust/source/anchors/
RUN /usr/bin/bupdate-ca-trust extract

## more stuff to actually run the app, etc

3 个答案:

答案 0 :(得分:0)

首先,您需要创建团队:

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
})

OR

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

更清晰

我假设您希望一个玩家属于一个团队(一对多的关系)。如果您认为某个玩家可能属于多个团队(通常不是这种情况,但我不知道您正在开发什么),那么您需要在Google上搜索Rails的多对多关系。

答案 1 :(得分:0)

@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
}])

答案 2 :(得分:0)

class Player中的关联错误,请查看何时必须使用:

如果无法从关联名称派生其他模型的名称,则可以使用:class_name选项提供模型名称。例如,如果某本书属于作者,但包含作者的模型的实际名称是Patron,那么您可以这样设置:

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

查看使用此关联的所有选项:Rails Guide