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

时间:2017-02-13 09:13:27

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

我在尝试解决鸡蛋和鸡蛋时遇到了这个错误。我的代码中的用户和团队的问题。我已经浏览了互联网,这似乎是一个常见的错误,根据我的情况,没有一个解决方案是有意义的。

最小可行范例:

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

user = User.new(name: "sudo", email: "foo@example.com")

然后是一个有效的团队:

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

获取ID:

id = team.save

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

user = User.new(name: "sudo", email: "foo@example.com", team: id)

这些命令的输出分别为:

=> #<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)

如果我尝试使用team.id,我会得到与#34; String()&#34;相同的错误。而不是&#34; TrueClass&#34;

我使用的是enable_extension&#34; uuid-ossp&#34; ,因此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

型号:

小组:

class Team < ApplicationRecord
    has_many :user
    has_one :owner
end

用户:

class User < ApplicationRecord
    belongs_to:team
end

架构:

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

如果我能提供更多信息,请告诉我。我对rails app开发缺乏经验。

1 个答案:

答案 0 :(得分:2)

使用

user = User.new(name: "sudo", email: "foo@example.com", team: team) 

因为在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`

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