尝试更新时在基本CRUD应用程序中出错:ActiveRecord :: StatementInvalid(SQLite3 :: SQLException:无此类列:addresses.player_id)

问题描述 投票:0回答:1

我正在使用Rails构建一个简单的CRUD应用。到目前为止,我要为Players设置CRUD。很快我将有HighSchoolTeamsClubTeamsAddresses

当我尝试更新现有播放器时遇到问题。我收到以下错误:

Started PATCH "/players/3" for ::1 at 2019-12-13 13:43:53 -0800
Processing by PlayersController#update as JS
  Parameters: {"authenticity_token"=>"2fyMlnOWCTn5pt8pyf/W86fRjCO4Af85sbl+3RFDg2OIXAU+T2wU7VxEU3gAxOZPNXvYDcjYpNXMWhImJiEkDQ==", "player"=>{"first_name"=>"Ben", "middle_name"=>"Patrick", "last_name"=>"Stein", "height"=>"", "weight"=>"", "birthday"=>"", "high_school_team"=>"", "club_team"=>"", "email"=>"", "phone_number"=>"", "address_line_one"=>"", "address_line_two"=>"", "city"=>"", "state"=>"", "zip"=>"", "notes"=>""}, "commit"=>"Update Player", "id"=>"3"}
  Player Load (0.2ms)  SELECT "players".* FROM "players" WHERE "players"."id" = ? LIMIT ?  [["id", 3], ["LIMIT", 1]]
  ↳ app/controllers/players_controller.rb:30:in `update'
   (0.1ms)  begin transaction
  ↳ app/controllers/players_controller.rb:32:in `update'
  Address Load (0.7ms)  SELECT "addresses".* FROM "addresses" WHERE "addresses"."player_id" = ? LIMIT ?  [["player_id", 3], ["LIMIT", 1]]
  ↳ app/controllers/players_controller.rb:32:in `update'
   (0.1ms)  rollback transaction
  ↳ app/controllers/players_controller.rb:32:in `update'
Completed 500 Internal Server Error in 14ms (ActiveRecord: 1.4ms | Allocations: 5907)

ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: addresses.player_id):

app/controllers/players_controller.rb:32:in `update'

我不确定该错误是怎么回事。确实没有addresses.player_id列。我不打算在那里。我打算让玩家通过拥有Address列来引用address_id

查看代码时,我没有发现任何问题。有效负载已成功到达服务器,并且播放器已成功加载。问题出在@player.update

players_controller.rb

class PlayersController < ApplicationController
  ...

  def edit
    @player = Player.find(params[:id])
  end

  def update
    @player = Player.find(params[:id])

    if @player.update(player_params)
      redirect_to @player
    else
      render 'edit'
    end
  end


  private
    def player_params
      params_for_player = params
        .require(:player)
        .permit(:first_name, :middle_name, :last_name, :height, :weight, :birthday, :high_school_team, :club_team, :email, :phone_number, :address_line_one, :address_line_two, :city, :state, :zip, :notes)
        .except(:address_line_one, :address_line_two, :city, :state, :zip)
      params_for_player["address"] = nil
      params_for_player["high_school_team"] = nil
      params_for_player["club_team"] = nil

      return params_for_player
    end
end

player.rb

class Player < ApplicationRecord
  has_one :address
  belongs_to :high_school_team, optional: true
  belongs_to :club_team, optional: true
end

address.rb

class Address < ApplicationRecord
end

schema.rb

ActiveRecord::Schema.define(version: 2019_12_12_025909) do

  create_table "addresses", force: :cascade do |t|
    t.string "line_one"
    t.string "line_two"
    t.string "city"
    t.string "state"
    t.string "zip"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "club_teams", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "high_school_teams", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "players", force: :cascade do |t|
    t.string "first_name"
    t.string "middle_name"
    t.string "last_name"
    t.decimal "height"
    t.decimal "weight"
    t.date "birthday"
    t.integer "high_school_team_id"
    t.integer "club_team_id"
    t.string "email"
    t.string "phone_number"
    t.integer "address_id"
    t.text "notes"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["address_id"], name: "index_players_on_address_id"
    t.index ["club_team_id"], name: "index_players_on_club_team_id"
    t.index ["high_school_team_id"], name: "index_players_on_high_school_team_id"
  end

  add_foreign_key "players", "addresses"
  add_foreign_key "players", "club_teams"
  add_foreign_key "players", "high_school_teams"
end
ruby-on-rails
1个回答
0
投票

我打算让玩家通过具有address_id列来引用地址。

class Player
  belongs_to :address
end

class Address
  has_one :player
end

[belongs_to用外键在模型上继续。

如果要在两个模型之间建立一对一关系,您将需要在其中添加一个“ belongs_to”,在另一个添加“ has_one”。怎么做你知道哪个吗?

区别在于放置外键的位置(它位于该表声明的belongs_to关联),但是您还应该考虑数据的实际含义。has_one关系表明某事是您的-那是,有些东西指向您。例如,它使更多说供应商拥有一个帐户比拥有一个帐户更有意义供应商。-Rails Guides: Associations

© www.soinside.com 2019 - 2024. All rights reserved.