ActiveRecord为id less表返回一个ghost null列

时间:2015-01-25 11:35:30

标签: ruby-on-rails postgresql activerecord

表格中只有9列。

duggout=# \d fantasy_selections
             Table "public.fantasy_selections"
     Column      |            Type             | Modifiers
-----------------+-----------------------------+-----------
 user_id         | integer                     |
 match_id        | integer                     |
 player_id       | integer                     |
 points          | integer                     |
 is_captain      | boolean                     |
 is_vice_captain | boolean                     |
 is_star_player  | boolean                     |
 created_at      | timestamp without time zone |
 updated_at      | timestamp without time zone |
Indexes:
    "index_fantasy_selections_on_user_id_and_match_id_and_player_id" UNIQUE, btree (user_id, match_id, player_id)

但是,当我查询表时,我得到10列,其中1列具有空键。这会在JSON序列化期间产生问题。检查以下哈希中的最后一个值。它是" nil => nil"。对于新记录,我没有看到空列。

在一个全新的Rails控制台中:

☁  duggout [master] ⚡ rails c
Loading development environment (Rails 4.1.4)

> f = FantasySelection.new
 => #<FantasySelection user_id: nil, match_id: nil, player_id: nil, points: nil, is_captain: nil, is_vice_captain: nil, is_star_player: nil, created_at: nil, updated_at: nil>

> f.attributes
=> {"user_id"=>nil, "match_id"=>nil, "player_id"=>nil, "points"=>nil, "is_captain"=>nil, "is_vice_captain"=>nil, "is_star_player"=>nil, "created_at"=>nil, "updated_at"=>nil, nil=>nil}

> FantasySelection.selection_of(99,6158).first.attributes
  FantasySelection Load (0.4ms)  SELECT  "fantasy_selections".* FROM "fantasy_selections"  WHERE "fantasy_selections"."user_id" = 99 AND "fantasy_selections"."match_id" = 6158 LIMIT 1
 => {"user_id"=>99, "match_id"=>6158, "player_id"=>1, "points"=>100, "is_captain"=>nil, "is_vice_captain"=>nil, "is_star_player"=>nil, "created_at"=>Sun, 25 Jan 2015 11:31:54 UTC +00:00, "updated_at"=>Sun, 25 Jan 2015 11:31:54 UTC +00:00, nil=>nil}

> FantasySelection.selection_of(99,6158).first.to_json
     `TypeError: nil is not a symbol` 

模特:

class FantasySelection < ActiveRecord::Base
  belongs_to :user
  belongs_to :match
  belongs_to :player

  scope :selection_of, ->(user_id, match_id) { where(user_id: user_id, match_id: match_id) }
end

此表的Schema.rb:

  create_table "fantasy_selections", id: false, force: true do |t|
    t.integer  "user_id"
    t.integer  "match_id"
    t.integer  "player_id"
    t.integer  "points"
    t.boolean  "is_captain"
    t.boolean  "is_vice_captain"
    t.boolean  "is_star_player"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "fantasy_selections", ["user_id", "match_id", "player_id"], name: "index_fantasy_selections_on_user_id_and_match_id_and_player_id", unique: true, using: :btree

请注意,此表没有id列。它是在id: false迁移期间使用create_table创建的。

可能是什么问题?

1 个答案:

答案 0 :(得分:0)

如果我说nil id 与任何事情无关,你会相信我吗?

我尝试重新创建错误,并决定深入了解。

追踪筹码

跟踪调用堆栈更有用,所以我尝试重新创建此错误。我按照......的方式做了一些事情。

TypeError: nil is not a symbol
    from /home/david/.rvm/gems/ruby-2.1.2/gems/activemodel-4.1.5/lib/active_model/serialization.rb:108:in `block in serializable_hash'
    from /home/david/.rvm/gems/ruby-2.1.2/gems/activemodel-4.1.5/lib/active_model/serialization.rb:108:in `each'
    from /home/david/.rvm/gems/ruby-2.1.2/gems/activemodel-4.1.5/lib/active_model/serialization.rb:108:in `serializable_hash'

这向我提出了要求转换为JSON的对象的问题。

在您的示例中,FantasySelection.selection_of(99,6158).first.to_json会返回错误,但如果在rails控制台中,则将其保存到实例:

a = FantasySelection.selection_of(99,6158).first.to_json

然后a.to_json事情正常。

<强>解释吗

在您的控制台中,请尝试

FantasySelection.selection_of(99,6158).first.class

然后,尝试

FantasySelection.selection_of(99,6158).first.attributes.class

您将看到可以将Hash转换为JSON,但不是第一个,这只是在控制台中返回的数据库结果。

我怀疑这可能无法解决您的问题(我只是解决您指向的rails控制台错误)。我希望这个链接很有用: rails 4 activerecord TypeError nil is not a symbol