我正在玩我的第一次关系。我有三个型号。他们在这里。
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :pools
has_many :games,
through: :pools
end
〜
class Pool < ActiveRecord::Base
has_many :users
has_many :games,
through: :users
end
〜
class Game < ActiveRecord::Base
belongs_to :user
belongs_to :pool
end
这个设置是否允许我在IRB中执行以下操作?
u=User.first
u.games
当我这样做时,我收到以下错误。
SystemStackError: stack level too deep
from /Users/ShiftedRec/.rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/irb/workspace.rb:86
Maybe IRB bug!
我应该可以做u.games和u.pools吗? 做一个pool.users和pool.games也很不错。
我如何更改模型设置以便可以访问这些方法..?
我一直在读书,但是has_many通过有点令人困惑。
这也是我的架构
ActiveRecord::Schema.define(version: 20140408165647) do
create_table "games", force: true do |t|
t.integer "pool_id"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "games", ["pool_id", "user_id"], name: "index_games_on_pool_id_and_user_id", unique: true
create_table "pools", force: true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "user_id" #vestige of old approach
end
create_table "users", force: true do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "users", ["email"], name: "index_users_on_email", unique: true
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
我很感激帮助!
答案 0 :(得分:5)
您收到错误是因为您的关联定义不正确。 Rails蠢蠢欲动,进行了递归。
更新您的模型Pool
和User
,如下所示:
class Pool < ActiveRecord::Base
has_many :games
has_many :users,
through: :games
end
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
has_many :games
has_many :pools,
through: :games
end
您正尝试在User
和Pool
到Game
之间创建 M-M关系。
另外,从user_id
表中移除pools
,因为您已通过联接表games
进行了关联。
此外,由于您在进行了上述更改后仍在rails console
(而不是IRB),请使用console
命令在reload!
中重新加载rails环境。
在Rails指南中详细了解 has-many-through-associations 。