我有一个user表,其中有一个referrer_id列,它跟踪邀请用户访问该站点的用户。referrer_id是进行引用的人的用户ID。
很简单。
这里的所有答案都是这样做的:
# models/users.rb
class User < ApplicationRecord
has_one :referrer, class_name: "User", foreign_key: :referrer_id
...
end以及相应的迁移:
class AddReferrerIdToUsers < ActiveRecord::Migration[6.0]
def change
add_column :users, :referrer_id, :bigint
end
end问题是:
# Let's create two users: Elon and my humble self
2.6.0 :009 > elon = User.create(name: "Elon", email: "elon@spacex.com")
=> #<User id: 6, name: "Elon", email: "elon@spacex.com", ..., referrer_id: nil>
2.6.0 :010 > me = User.create(name: "FloatingRock", email: "floating@rock.com")
=> #<User id: 7, name: "FloatingRock", email: "floating@rock.com", ..., referrer_id: nil>
# I'm referring Elon to the site
2.6.0 :011 > elon.update(referrer: me)
=> true输出是倒置的-- referrer_id设置在elon上,而不是我:
# Huh? Why's his referrer_id nil??
2.6.0 :012 > elon
=> #<User id: 6, name: "Elon", ..., referrer_id: nil>
# The logic is inverted! Rails thinks I was referred by him, the wrong way roun
2.6.0 :013 > me
=> #<User id: 7, name: "FloatingRock", ..., referrer_id: 6>发布于 2020-03-24 18:29:52
对于has_one和belongs_to,您已经陷入了一个非常常见的误解,这是由于语义有些混乱。has_one规定,存在一对一的关联,而外键位于关联的另一端--就像has_many一样(除了明显的差异)。
belongs_to将外键放置在此模型上。或者在自引用关联的情况下,表示该关联与外键相对应。
class AddReferrerIdToUsers < ActiveRecord::Migration[6.0]
def change
add_reference :users, :referrer, foreign_key: { to_table: :users }
end
end
# models/users.rb
class User < ApplicationRecord
belongs_to :referrer,
class_name: "User",
inverse_of: :referrals
has_many :referrals,
class_name: "User",
inverse_of: :referrer,
foreign_key: :referrer_id
end如果您真的想使关联成为一对一(用户只能引用另一个用户),则可以使用引用belongs_to分类的belongs_to:
# models/users.rb
class User < ApplicationRecord
belongs_to :referrer,
class_name: "User",
inverse_of: :referred_user
has_one :referred_user,
class_name: "User",
inverse_of: :referrer,
foreign_key: :referrer_id
endhttps://stackoverflow.com/questions/60825903
复制相似问题