我试图在Rails应用程序上创建一个推荐程序,我与关系斗争。
我的推荐模型很简单:godfather_id
,godson_id
,state
教父id和教子id都引用一个User,该User可以有多个教子id,但只能有一个教父id。
class Referral < ApplicationRecord
belongs_to :user
belongs_to :godson, class_name: 'User'
end
问题出现在我的用户模型中。我不想做user.godsons
来获得教子用户的数组,user.godfather
来获得教父用户。
我尝试了一些东西,我认为这两个是最接近我需要做的(用户模型简化的例子)。
class User < ApplicationRecord
has_many :referrals
has_many :godson, -> { where(godfather_id: id) }, through: :referrals
has_one :godfather, -> { where(godson_id: id) }, through: :referrals
end
class User < ApplicationRecord
has_many :godson_relations, class_name: 'Referral', foreign_key: 'godson_id'
has_many :godsons, through: :godson_relations
has_one :godfather_relation, class_name: 'Referral', foreign_key: 'godfather_id'
has_one :godfather, through: :godfather_relations
end
我真的不确定如何实现这种关系,任何帮助将不胜感激🙏
要创建一个实际的自引用关联,只需在users表上添加一个列,该列指向同一个表:
class AddGodfatherToUsers < ActiveRecord::Migration[6.1]
def change
add_reference :users, :godfather, null: true,
foreign_key: { to_table: :users }
end end
class User
belongs_to :god_father,
class_name: 'User',
optional: true,
inverse_of: :god_children
has_many :god_children,
class_name: 'User',
foreign_key: :god_father_id
inverse_of: :god_father
end
如果你必须将Referalls存储为一个单独的表,那么你的方向是正确的,但是你把外键弄反了:
class Referral < ApplicationRecord
# you better be explicit here or its going to get extremely confusing
belongs_to :godfather, class_name: 'User'
belongs_to :godson, class_name: 'User'
end
class User < ApplicationRecord
has_many :referrals_as_godfather,
class_name: 'Referral', foreign_key: 'godfather_id'
has_one :referral_as_godson,
class_name: 'Referral',
foreign_key: 'godfather_id'
has_many :godsons, through: :referrals_as_godfather
has_one :godfather, through: :referral_as_godson
end
需要注意的是,has_one
并不能保证一个用户只能有一个推荐人(也就是一个教父)。它只是向查询添加了一个LIMIT 1。您必须使用唯一性约束和验证来强制执行。