Rails:ActiveRecord::AssociationTypeMismatch Team() 预期,得到 String()

Nic*_*ios 2 ruby activerecord ruby-on-rails ruby-on-rails-5

我在尝试解决代码中的用户和团队的“先有鸡还是先有蛋”问题时遇到了此错误。我在互联网上搜索过,这似乎是一个常见的错误,考虑到我的情况,没有一个解决方案有意义。

最小可行示例:

在 Rails 控制台上,我创建了一个新的(无效)用户:

user = User.new(name: "sudo", email: "foo@example.com")
Run Code Online (Sandbox Code Playgroud)

然后是一个有效的团队:

team = Team.new( name: "Test team, please ignore", tier: 0, owner: user.id, users: user.id)
Run Code Online (Sandbox Code Playgroud)

获取ID:

id = team.save
Run Code Online (Sandbox Code Playgroud)

然后尝试创建一个有效用户:

user = User.new(name: "sudo", email: "foo@example.com", team: id)
Run Code Online (Sandbox Code Playgroud)

这些命令的输出分别是:

=> #<User id: nil, name: "sudo", email: "foo@example.com", team_id: nil, created_at: nil, updated_at: nil>
=> #<Team id: nil, name: "Test team, please ignore", tier: 0, owner: nil, users: nil, created_at: nil, updated_at: nil>
ActiveRecord::AssociationTypeMismatch: Team(#47180498893940) expected, got TrueClass(#47180477068240)
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用team.id,我会收到与“String()”而不是“TrueClass”相同的错误

我正在使用 enable_extension "uuid-ossp",因此 ID 不应该是连续的。

在这两种情况下,我都对为什么 ID 为零,或者为什么不匹配"Team(##47180498893940)"而不是"52b9f290-61e7-48b3-99a9-b0fb64d68b51"像输出所team.id建议的那样感到困惑。

测试:

我的测试也给出了字符串错误:

class UserTest < ActiveSupport::TestCase
   def setup
    @team = Team.new(name: "Example Team", tier: 0, owner: "00000000-0000-0000-0000-000000000000")
    @user = User.new(name: "Example User", email: "user@example.com", team: team_id)
  end

  test "should be valid" do
    assert @user.valid?
  end
end
Run Code Online (Sandbox Code Playgroud)

楷模:

团队:

class Team < ApplicationRecord
    has_many :user
    has_one :owner
end
Run Code Online (Sandbox Code Playgroud)

用户:

class User < ApplicationRecord
    belongs_to:team
end
Run Code Online (Sandbox Code Playgroud)

架构:

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

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
enable_extension "uuid-ossp"

create_table "teams", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t|
  t.string   "name"
  t.integer  "tier"
  t.string   "owner"
  t.string   "users"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

create_table "users", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t|
  t.string   "name"
  t.string   "email"
  t.string   "team_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end
end
Run Code Online (Sandbox Code Playgroud)

如果我可以提供更多信息,请告诉我。我在 Rails 应用程序开发方面缺乏经验。

Saj*_*jan 5

使用

user = User.new(name: "sudo", email: "foo@example.com", team: team) 
Run Code Online (Sandbox Code Playgroud)

因为在 中id = team.save,它将存储truefalse。根据代码是否成功保存对象或发生任何错误(例如验证错误),它将分别返回truefalse

如果您想使用 ID 保存,请尝试如下操作:

team = Team.new(...) # create team with right attributes inside `new`
team.save
user = User.new(name: "sudo", email: "foo@example.com", team_id: team.id) # notice the `team_id`
Run Code Online (Sandbox Code Playgroud)

由于您将按 id 保存,因此应直接使用 forign_key 列名称。否则,如果您使用team属性,那么您将必须提供一个Team对象,而不是像 id 这样的整数对象(例如 21)。